sql >> Database teknologi >  >> RDS >> Sqlserver

SQL Server-forespørgsel:rækker laver kolonner (pivot?)

Pivotering er meget ligesom gruppering. Du kan se det som begrænset gruppering med en 'særlig effekt'. Begrænsningen består i, at der kun kan være én aggregeret kolonne. (I normal GROUP BY-forespørgsel kan du naturligvis have mere end én.) Og med den 'specielle effekt' mener jeg selvfølgelig, at en af ​​de andre kolonner (og igen kun én) bliver transformeret til flere kolonner.

Lad os tage din GROUP BY-forespørgsel som et eksempel. Du har tre kolonner i outputtet. En af dem, Count , er selve kolonnen, der indeholder aggregerede oplysninger. Det er den, der ville være spredt blandt flere kolonner i en PIVOT-forespørgsel. En anden kolonne, Priority , er en af ​​de to andre kolonner, som resultaterne er grupperet efter, og også den, der skal pivoteres. Til sidst EntryDate er den anden GROUP BY kolonne. Den skal simpelthen blive som den er, for den er ikke direkte med til at pivotere.

Lad os nu se, hvordan dit primære SELECT bliver transformeret fra en sædvanlig GROUP BY-forespørgsel til en PIVOT-forespørgsel, trin for trin:

  1. Da gruppering er underforstået i en PIVOT-forespørgsel, fjernes GROUP BY-sætningen. I stedet indføres en PIVOT-klausul.

  2. Count kolonnens udtryk flyttes fra SELECT-udtrykket til PIVOT-udtrykket.

  3. Opdelingen af ​​Priority kolonne er defineret i PIVOT-sætningen.

  4. Priority og Count kolonner i SELECT-klausulen erstattes af listen over kolonner, der er defineret i PIVOT-klausulen.

  5. EntryDate kolonne forbliver uændret i SELECT-sætningen.

Og her er den resulterende forespørgsel med kommentarer, der markerer hver del af transformationen beskrevet ovenfor:

WITH TATH(Priority, EntryDate) AS 
(
    SELECT TH.Priority as Priority, DATEADD(dd, 0, DATEDIFF(dd, 0, entryDate)) as EntryDate
      FROM TicketAssignment TA, TicketHeader TH 
     WHERE TA.TicketID = TH.TicketID   
       AND TA.Company = 'IT'
       AND TA.CurrentRole IN ('SA1B','SA1C','SDA')
) 
SELECT
  convert(varchar(10), EntryDate,103) as EntryDate,                       -- #5
  [0] AS Priority0, [1] AS Priority1, [2] AS Priority2, [3] AS Priority3  -- #4
FROM TATH
PIVOT (                                                                   -- #1
  COUNT(*)                                                                -- #2
  FOR Priority IN ([0], [1], [2], [3])                                    -- #3
) p

/*  -- your original main query, for comparison
SELECT
  Priority,                                                               -- #4
  convert(varchar(10),                                                    -- #5
  EntryDate,103) as EntryDate, COUNT(*) AS Count                          -- ##2&4
FROM TATH 
GROUP BY Priority, EntryDate                                              -- #1
*/

Der er en ekstra note på kolonnelisten i PIVOT-klausulen. Først og fremmest skal du forstå, at det resulterende sæt af en SQL-forespørgsel formodes at være rettet med hensyn til antallet af kolonner og deres navne. Det betyder, at du eksplicit skal opregne alle de transformerede kolonner, du ønsker at se i outputtet. Navnene er afledt af værdierne i den kolonne, der pivoteres, men de skal angives som navne , ikke som værdier. Derfor kan du se firkantede parenteser omkring de anførte tal. Da tallene ikke i sig selv opfylder reglerne for almindelige identifikatorer , skal de afgrænses.

Du kan også se, at du kan kalde pivoterede kolonner i SELECT-sætningen ligesom enhver anden kolonne eller udtryk. Så i sidste ende behøver du ikke ende med det meningsløse 0 , 1 etc. identifikatorer, og i stedet kan du tildele disse kolonner et hvilket som helst navn, du vil.

Hvis du ønsker, at antallet og/eller navnene på de pivoterede kolonner skal være dynamiske, skal du bygge forespørgslen dynamisk, dvs. indsamle navnene først og derefter inkorporere dem i en streng, der indeholder resten af forespørg og påkald den endelige forespørgsel med EXEC () eller EXEC sp_executesql . Du kan søge på dette websted for mere information om dynamisk pivoting.




  1. Hvordan man erklærer en talvariabel, hvor jeg kan gemme tabellens antal i min løkke

  2. Kan SQL*Plus læse miljøvariabler fra den maskine, den kører på?

  3. Parse fejl:syntaksfejl, uventet 'mysql_query' (T_STRING) i

  4. Python MySQLdb undtagelser