Pivoting je velmi podobný seskupování. Můžete to vidět jako omezené seskupení se „zvláštním efektem“. Omezení spočívá v tom, že může být pouze jeden agregovaný sloupec. (V normálním dotazu GROUP BY můžete mít samozřejmě více než jeden.) A tím „zvláštním efektem“ mám samozřejmě na mysli, že jeden z ostatních sloupců (a opět pouze jeden) se transformuje do více sloupců.
Vezměme si jako příklad váš dotaz GROUP BY. Ve výstupu máte tři sloupce. Jeden z nich, Count
, je samotný sloupec, který obsahuje agregované informace. To je ten, který by byl rozptýlen ve více sloupcích v PIVOT dotazu. Další sloupec, Priority
, je jedním ze dvou dalších sloupců, podle kterých jsou výsledky seskupeny, a také sloupcem, který je třeba otočit. Nakonec EntryDate
je druhý sloupec GROUP BY. Mělo by jednoduše zůstat tak, jak je, protože se přímo neúčastní otáčení.
Podívejme se nyní, jak se váš hlavní SELECT transformuje z obvyklého dotazu GROUP BY na dotaz PIVOT, krok za krokem:
-
Protože seskupení je zahrnuto v dotazu PIVOT, klauzule GROUP BY je odstraněna. Místo toho je zavedena klauzule PIVOT.
-
Count
výraz sloupce se přesune z klauzule SELECT do klauzule PIVOT. -
Rozdělení
Priority
sloupec je definován v klauzuli PIVOT. -
Priority
aCount
sloupce v klauzuli SELECT jsou nahrazeny seznamem sloupců definovaných v klauzuli PIVOT. -
EntryDate
sloupec zůstane v klauzuli SELECT nezměněn.
A zde je výsledný dotaz s komentáři označujícími každou část transformace popsané výše:
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
*/
V seznamu sloupců v klauzuli PIVOT je ještě jedna poznámka. Nejprve musíte pochopit, že výsledná sada SQL dotazu má být pevně daná, pokud jde o počet sloupců a jejich názvy. To znamená, že musíte explicitně vyjmenovat všechny transformované sloupce, které chcete vidět ve výstupu. Názvy jsou odvozeny z hodnot sloupce, který je pivotován, ale měly by být zadány jako názvy , ne jako hodnoty. Kolem uvedených čísel proto vidíte hranaté závorky. Protože samotná čísla nesplňují pravidla pro běžné identifikátory , musí být ohraničeny.
Můžete také vidět, že můžete alias pivotovaných sloupců v klauzuli SELECT stejně jako jakýkoli jiný sloupec nebo výraz. Takže nakonec nemusíte skončit u nic neříkajícího 0
, 1
atd. a místo toho můžete těmto sloupcům přiřadit libovolné názvy.
Pokud chcete, aby počet a/nebo názvy pivotovaných sloupců byly dynamické, budete muset vytvořit dotaz dynamicky, tj. nejprve shromáždit názvy a poté je začlenit do řetězce obsahujícího zbytek dotaz a vyvolejte konečný dotaz pomocí EXEC ()
nebo EXEC sp_executesql
. Můžete prohledávat tento web
pro více informací o dynamickém otáčení.