Завъртането е много подобно на групирането. Можете да го разглеждате като ограничено групиране със „специален ефект“. Ограничението се състои в това, че може да има само една обобщена колона. (При нормална заявка GROUP BY можете да имате повече от една, естествено.) И под „специалния ефект“ имам предвид, разбира се, че една от другите колони (и отново само една) се трансформира в множество колони.
Да вземем за пример вашата заявка GROUP BY. Имате три колони в изхода. Един от тях, Count
, е същата колона, която съдържа обобщена информация. Това е тази, която ще бъде разпръсната между множество колони в PIVOT заявка. Друга колона, Priority
, е една от другите две колони, по които са групирани резултатите, а също и тази, която трябва да се завърти. И накрая, EntryDate
е другата колона GROUP BY. Просто трябва да остане такъв, какъвто е, защото не участва пряко в завъртането.
Нека сега да видим как вашият основен SELECT се трансформира от обикновена GROUP BY заявка в PIVOT заявка, стъпка по стъпка:
-
Тъй като групирането се подразбира в PIVOT заявка, клаузата GROUP BY се премахва. Вместо това се въвежда клауза PIVOT.
-
Count
изразът на колоната се премества от клаузата SELECT в клаузата PIVOT. -
Разделянето на
Priority
колона е дефинирана в клаузата PIVOT. -
Priority
иCount
колоните в клаузата SELECT се заменят със списъка на колоните, дефинирани в клаузата PIVOT. -
EntryDate
колона остава непроменена в клаузата SELECT.
И ето получената заявка с коментари, маркиращи всяка част от трансформацията, описана по-горе:
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
*/
Има една допълнителна бележка в списъка с колони в клаузата PIVOT. На първо място, трябва да разберете, че полученият набор от SQL заявка трябва да бъде фиксиран по отношение на броя на колоните и техните имена. Това означава, че трябва изрично да изброите всички трансформирани колони, които искате да видите в изхода. Имената се извличат от стойностите на колоната, която се завърта, но трябва да бъдат посочени като имена , а не като ценности. Ето защо можете да видите квадратни скоби около изброените числа. Тъй като самите числа не отговарят на правилата за обикновени идентификатори , те трябва да бъдат разделени.
Можете също така да видите, че можете да създавате псевдоними на завъртени колони в клаузата SELECT точно като всяка друга колона или израз. Така че в крайна сметка не е нужно да се окажете с безсмисления 0
, 1
и т.н. идентификатори и вместо това можете да присвоите на тези колони произволни имена.
Ако искате броят и/или имената на завъртените колони да бъдат динамични, ще трябва да изградите заявката динамично, т.е. първо да съберете имената, след което да ги включите в низ, съдържащ останалата част от заявка и извикване на последната заявка с EXEC ()
или EXEC sp_executesql
. Можете да търсите в този сайт
за повече информация относно динамичното завъртане.