Pivotering är ungefär som att gruppera. Du kan se det som en begränsad gruppering med en "speciell effekt". Begränsningen består i att det bara kan finnas en aggregerad kolumn. (I normal GROUP BY-fråga kan du naturligtvis ha mer än en.) Och med "specialeffekten" menar jag naturligtvis att en av de andra kolumnerna (och återigen bara en) omvandlas till flera kolumner.
Låt oss ta din GROUP BY-fråga som ett exempel. Du har tre kolumner i utgången. En av dem, Count
, är själva kolumnen som innehåller aggregerad information. Det är den som skulle vara utspridda bland flera kolumner i en PIVOT-fråga. En annan kolumn, Priority
, är en av de två andra kolumnerna som resultaten grupperas efter och även den som behöver pivoteras. Slutligen, EntryDate
är den andra GROUP BY-kolumnen. Den ska helt enkelt stanna som den är, eftersom den inte direkt deltar i svängningen.
Låt oss nu se hur din huvudsakliga SELECT förvandlas från en vanlig GROUP BY-fråga till en PIVOT-fråga, steg för steg:
-
Eftersom gruppering är underförstått i en PIVOT-fråga tas GROUP BY-satsen bort. Istället införs en PIVOT-klausul.
-
Count
kolumns uttryck flyttas från SELECT-satsen till PIVOT-satsen. -
Uppdelningen av
Priority
kolumnen definieras i PIVOT-satsen. -
Priority
ochCount
kolumner i SELECT-satsen ersätts av listan över kolumner som definieras i PIVOT-satsen. -
EntryDate
kolumnen förblir oförändrad i SELECT-satsen.
Och här är den resulterande frågan, med kommentarer som markerar varje del av transformationen som beskrivs ovan:
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
*/
Det finns ytterligare en anmärkning på kolumnlistan i PIVOT-satsen. Först och främst måste du förstå att den resulterande uppsättningen av en SQL-fråga är tänkt att vara fixerad när det gäller antalet kolumner och deras namn. Det betyder att du uttryckligen måste räkna upp alla transformerade kolumner du vill se i utdata. Namnen härleds från värdena i kolumnen som pivoteras men de bör anges som namn , inte som värden. Det är därför du kan se hakparenteser runt de listade siffrorna. Eftersom siffror i sig inte uppfyller reglerna för vanliga identifierare , måste de vara avgränsade.
Du kan också se att du kan alias pivoterade kolumner i SELECT-satsen precis som alla andra kolumner eller uttryck. Så i slutändan behöver du inte sluta med den meningslösa 0
, 1
etc. identifierare och istället kan du tilldela dessa kolumner vilka namn du vill.
Om du vill att numret och/eller namnen på de pivoterade kolumnerna ska vara dynamiska måste du bygga frågan dynamiskt, dvs samla in namnen först och sedan infoga dem i en sträng som innehåller resten av fråga och anropa den sista frågan med EXEC ()
eller EXEC sp_executesql
. Du kan söka på den här webbplatsen
för mer information om dynamisk pivotering.