SQL Serverのピボット演算子は、集計結果セットの各行を出力セットの対応する列に変換します。ピボット演算子は、クロス集計クエリを作成する場合に特に便利です。
実際にどのように機能するかを見てみましょう。
データの準備
まず、ピボット演算子を実装するために使用できるダミーデータを作成しましょう。
CREATE DATABASE schooldb
CREATE TABLE student
(
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
gender VARCHAR(50) NOT NULL,
DOB datetime NOT NULL,
total_score INT NOT NULL,
city VARCHAR(50) NOT NULL
)
INSERT INTO student
VALUES (1, 'Jolly', 'Female', '12-JUN-1989', 500, 'London'),
(2, 'Jon', 'Male', '02-FEB-1974', 545, 'Manchester'),
(3, 'Sara', 'Female', '07-MAR-1988', 600, 'Leeds'),
(4, 'Laura', 'Female', '22-DEC-1981', 400, 'Liverpool'),
(5, 'Alan', 'Male', '29-JUL-1993', 500, 'London'),
(6, 'Kate', 'Female', '03-JAN-1985', 500, 'Liverpool'),
(7, 'Joseph', 'Male', '09-APR-1982', 643, 'London'),
(8, 'Mice', 'Male', '16-AUG-1974', 543, 'Liverpool'),
(9, 'Wise', 'Male', '11-NOV-1987', 499, 'Manchester'),
(10, 'Elis', 'Female', '28-OCT-1990', 400, 'Leeds');
ピボットオペレーターはどのように機能しますか?
SQLデータをグループ化する標準的な方法は、GroupBy句を使用することです。都市ごとにグループ化された、学生テーブルのtotal_score列の値の平均を計算するクエリを作成しましょう。
USE schooldb
SELECT
city,
AVG(total_score) as Avg_Score
FROM
student
GROUP BY
city
これにより、次の結果が得られます。
[テーブルID=25 /]
都市名が列に表示され、各列にその都市に属する学生のtotal_scoreの平均値が含まれる結果セットが必要な場合はどうなりますか?このようなもの:
[テーブルID=26 /]
ここで、ピボットオペレーターが便利です。
ベースデータの選択
ピボット演算子を使用する場合の最初のステップは、ピボット演算子の基になるベースデータを選択することです。データを都市ごとにグループ化し、その都市に属する学生のtotal_scoreの平均を求めます。したがって、cityとtotal_scoreを選択する単純なSELECTステートメントを作成する必要があります。
SELECT
city,
total_score
FROM
student
一時データセットの作成
これで、理想的には、前のセクションで作成したベースデータにピボット演算子を直接適用できるようになりますが、残念ながらできません。ピボット演算子を機能させるには、ピボット演算子を適用できるテーブル値の式を作成する必要があります。ここにはさまざまな選択肢があります。派生テーブル、共通テーブル式(CTE)を使用することも、一時テーブルを作成することもできます。
この例では、すばやく簡単な派生テーブルを使用します。前のセクションで作成した基本的なselectステートメントを使用してこれを行うには、それを括弧のセットでラップしてから、エイリアスを適用します。最後に、その派生テーブルからすべてを選択します。
SELECT * FROM
(SELECT
city,
total_score
FROM
student
)
AS StudentTable
ピボット演算子の適用
基本データを準備し、派生テーブルを作成したので、ピボット演算子を適用します。
これを行うには、派生テーブルの最後に「PIVOT」を挿入し、その後に一連の括弧を挿入して、このピボットテーブルにエイリアスを付けます。
括弧内には、いくつかの重要な情報を指定する必要があります。
- 集計関数を適用するフィールドを指定する必要があります。この例では、「total_score」列にAVG集計関数を適用します。
- 次に、データをピボットするベースデータのどの列を指定する必要があります。これを行うには、「FOR」の後に、この例では都市である列名を続けます。
- 最後のステップは少しイライラします。ピボットテーブルの見出しにしたい都市の列の値をリストする必要があります。 IN演算子の後に括弧のセットを使用します。括弧内では、角括弧内に各列の名前を書き込むコンマ区切りのリストを使用します。この例では、ピボットテーブルの見出し名としてロンドン、リーズ、マンチェスターが必要なので、次の形式で記述します:([ロンドン]、[リーズ]、[マンチェスター])。
USE schooldb
SELECT * FROM
(SELECT
city,
total_score
FROM
student
)
AS StudentTable
PIVOT(
AVG(total_score)
FOR city IN ([London],[Liverpool],[Leeds],[Manchester])
) AS StudentPivotTable
上記のクエリを実行すると、結果は次のようになります。
[テーブルID=27 /]
ピボットテーブルへの行グループの追加
前のセクションでは、ピボット演算子を使用して行グループを列グループに変換する方法を説明しました。ただし、行グループを列グループとともにピボットテーブルに追加することもできます。
たとえば、都市別および性別別にグループ化されたすべての学生のtotal_score列の平均値を検索する場合は、ピボットテーブル内で列グループと行グループを組み合わせて使用できます。ここで、各列は都市名を表し、各行は学生の性別を表します。
幸い、ピボットテーブルに行グループを追加するために追加のスクリプトを作成する必要はありません。基本データセット内で、行グループとして追加する列名をピボットテーブルに追加するだけです。
USE schooldb
SELECT * FROM
(SELECT
city,
gender,
total_score
FROM
student
)
AS StudentTable
PIVOT(
AVG(total_score)
FOR city IN ([London],[Liverpool],[Leeds],[Manchester])
) AS StudentPivotTable
上記のスクリプトでは、基本のSELECTステートメントに「gender」列を追加しただけです。
上記のクエリの出力は次のようになります:
[テーブルID=28 /]
これはクロス集計です。たとえば、結果から、ロンドンに住む女子学生の平均合計スコアは500であることがわかります。同様に、ロンドンに住む男子学生の平均合計スコアは571です。
お読みください:
QUOTENAME関数を使用した動的ピボットテーブルの作成