ピボットはグループ化によく似ています。 「特殊効果」を備えた限定的なグループ化と見なすことができます。制限は、集計された列が 1 つしか存在できないことにあります。 (通常の GROUP BY クエリでは、当然のことながら、複数の列を持つことができます。) そして、「特殊効果」とは、もちろん、他の列の 1 つ (そして、1 つだけ) が複数の列に変換されることを意味します。
GROUP BY クエリを例に取りましょう。出力には 3 つの列があります。そのうちの 1 つ、Count
、まさに集約された情報を含む列です。これは、PIVOT クエリの複数の列に散在するものです。別の列、Priority
は、結果がグループ化される他の 2 つの列の 1 つであり、ピボットが必要な列でもあります。最後に、EntryDate
もう 1 つの GROUP BY 列です。ピボットには直接関与しないため、そのままにしておく必要があります。
メインの SELECT が通常の GROUP BY クエリから PIVOT クエリにどのように変換されるかを段階的に見てみましょう:
<オール> <リ>PIVOT クエリではグループ化が暗示されるため、GROUP BY 句は削除されます。代わりに、PIVOT 句が導入されています。
<リ>
カウント
列の式は SELECT 句から PIVOT 句に移動されます。
Priority
の分割 列は PIVOT 句で定義されています。
優先度
そしてカウント
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 -- #4FROM TATHPIVOT ( -- #1 COUNT(*) -- #2 FOR Priority IN ([0], [1] ], [2], [3]) -- #3) p/* -- 比較のための元のメイン クエリSELECT Priority, -- #4 convert(varchar(10), -- #5 EntryDate,103) as EntryDate , COUNT(*) AS カウント-- ##2&4FROM TATH GROUP BY Priority, EntryDate -- #1*/
プレ>PIVOT 句の列リストには、もう 1 つ注意事項があります。まず第一に、SQL クエリの結果セットは、列の数とその名前に関して固定されていることを理解する必要があります。つまり、出力に表示するすべての変換された列を明示的に列挙する必要があります。名前は、ピボットされる列の値から派生しますが、names として指定する必要があります 、値としてではありません。そのため、リストされた数字の周りに角括弧が表示されます。番号自体は 通常の識別子 、それらを区切る必要があります。
また、他の列や式と同様に、SELECT 句でピボットされた列にエイリアスを設定できることもわかります。したがって、結局、意味のない
0
で終わる必要はありません。 ,1コード> などの識別子であり、代わりにそれらの列に好きな名前を割り当てることができます。
ピボットされた列の数や名前を動的にしたい場合は、クエリを動的に作成する必要があります。つまり、最初に名前を収集してから、残りの列を含む文字列にそれらを組み込みます。
EXEC ()
でクエリを実行し、最終クエリを呼び出します またはEXEC sp_executesql
. このサイトを検索 できます 動的ピボットの詳細については、