Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

PIVOTとは

PIVOTとは、テーブル値式の1つの列にある一意の値を取得し、出力内の複数の列に変換することにより、テーブル値式を行列変換する関係演算子です。

少し複雑な説明になってしまいましたが、簡単に説明すると「行を列に変換」してくれます。

PIVOTで集計が実行されるのは、最終出力で必要な残りの任意の列値に対して集計が必要な場合です。

実際にPIVOTの使い方を見て確認していきましょう。

PIVOTの使い方

PIVOTの基本的な使い方・構文は次のとおりです。

  1. SELECT
  2. PIVOT列の値1,
  3. PIVOT列の値2,
  4. PIVOT列の値3,
  5. ・・・
  6. FROM テーブル名
  7. PIVOT (
  8. 集計関数(集計対象列)
  9. FOR PIVOT
  10. IN (PIVOT列の値1, PIVOT列の値2, PIVOT列の値3, ・・・)
  11. ) AS PIVOTテーブルの別名

サンプルで動きを確認してみましょう。

my_tableには、次のデータがあると仮定します。

name score
s1 126
s2 220
s3 60
s2 500
s1 270
s1 388
s3 200

nameとscoreの2列からなるmy_tableテーブルをもとに、PIVOTでnameごとに列を作成し、scoreの平均値を集計しましょう。

PIVOTは次のように記述します。

  1. SELECT
  2. s1,
  3. s2,
  4. s3
  5. FROM my_table
  6. PIVOT (AVG(score) FOR name IN (s1, s2, s3)) AS pivot_table
  7. s1 s2 s3
  8. ----------- ----------- -----------
  9. 238 470 130

IN句で指定したnameが列になり、scoreの平均値が値となったpivot_tableができました。

UNPIVOTの使い方

UNPIVOTは、PIVOTの逆でテーブル値式の列を行に変換します。

こちらも使い方を見ていきましょう。

  1. SELECT
  2. UNPIVOT列をまとめる列,
  3. UNPIVOT列の値が入る列
  4. FROM テーブル名
  5. UNPIVOT (
  6. UNPIVOT列の値が入る列
  7. FOR UNPIVOT列をまとめる列
  8. IN (UNPIVOT列の値1, UNPIVOT列の値2, UNPIVOT列の値3 ・・・)
  9. ) AS UNPIVOTテーブルの別名

サンプルで動きを確認してみましょう。

my_tableテーブルに、s1・s2・s3の3列を用意します。

そして、s1・s2・s3をname列に、各列の値をscore列に集計します。

  1. SELECT
  2. name,
  3. score
  4. FROM my_table
  5. UNPIVOT (score FOR name IN (s1, s2, s3)) AS unpivot_table;
  6.  
  7. name score
  8. ----------- -----------
  9. s1 126
  10. s2 220
  11. s3 60
  12. s2 500
  13. s1 270
  14. s1 388
  15. s3 200

IN句に指定したs1〜s3列をname列の値に変換し、IN句に指定したそれぞれの列の値がscore列の値となっているのがわかります。

PIVOTで合計を求める

PIVOTを使って列ごとの合計を求めてみましょう。

合計を求める場合は「SUM」を使います。

先ほどの「PIVOTの使い方」で使用したテーブルで確認してみましょう。

  1. SELECT
  2. s1,
  3. s2,
  4. s3
  5. FROM my_table
  6. PIVOT (SUM(score) FOR name IN (s1, s2, s3)) AS pivot_table;
  7.  
  8.   s1 s2 s3
  9. ----------- ----------- -----------
  10. 784 720 260

列ごとの合計を表示できるはずです。

PIVOTで動的SQLを活用する

行列の変換ができるPIVOT、UNPIVOTは非常に便利な機能ですが、このままだとIN句の指定は静的なものだけに限られてしまいます。

例えば、先ほどのテーブルのnameに「s4」のレコードを追加しても、s4のレコードは取得できません。

新しいnameが追加されるごとに指定を追加してもよいのですが、SQLを修正する必要があるので少し不便です。

そのため、レコードの追加に合わせて動的に指定を変更したい場合は「動的SQL」を活用しましょう。

動的SQLを使うと、nameの種類が増えても修正する必要がありません。

PIVOTの使い方で使用したSQLを、動的SQLに変更する場合は次のようになります。

  1. DECLARE @score_list varchar(max)
  2. DECLARE @sql nvarchar(max)
  3. SET @score_list = null
  4. SELECT
  5. @score_list =
  6. CASE
  7. WHEN @score_list IS NULL THEN '[' + name + ']'
  8. ELSE @score_list + ', [' + name + ']'
  9. END
  10. FROM my_table
  11. GROUP BY name
  12.  
  13. SET @sql =
  14. 'SELECT * FROM my_table PIVOT (AVG(score) FOR name in (' +
  15. @score_list +
  16. ')) AS pivot_table'
  17. EXEC sp_executesql @sql;

@score_listを作成するSELECT文で、my_tableテーブルにあるnameをカンマ区切りでつなげています。

そして、SQL文のIN句に商品名@score_listを指定し、実行すれば動的にnameとその値のレコードを取得できます。

MySQLでpivotを実現

MySQLではPIVOTを使用することができません。

そのためPIVOT(行列変換)を実現するには、SQLを工夫する必要があります。

ここでは、次のデータを使って行列変換してみましょう。

id type_id type_name value
1 1 name Satou
1 2 age 25
1 3 sex Male
2 1 name Takahashi
2 2 age 33
2 3 sex Female
3 1 name Abe
3 2 age 29
3 3 sex Male
  1. SELECT id,
  2. (SELECT value FROM my_table WHERE type_name = 'name' AND id = m.id) AS name,
  3. (SELECT value FROM my_table WHERE type_name = 'age' AND id = m.id) AS age,
  4. (SELECT value FROM my_table WHERE type_name = 'sex' AND id = m.id) AS sex FROM my_table m
  5. GROUP BY id;
  6. id name age sex
  7. ----------- ----------- ----------- -----------
  8. 1 Satou 25 Male
  9. 2 Takahashi 33 FeMale
  10. 3 Abe 29 Male

SELECTの部分でname、age、sexごとに列を作成し、idごとにGROUP BYで並べます。

PIVOTで複数列変換する

PIVOTで複数列を行列変換する際は、INの中の指定でASによる別名をつけて指定しましょう。

変換するのは次のデータです。

id score time
s1 126 60
s2 220 100
s3 60 25
s2 500 260
s1 270 120
s1 388 175
s3 200 140
  1. SELECT
  2. pv.S1_score,
  3. pv.S1_time,
  4. pv.S2_score,
  5. pv.S2_time,
  6. pv.S3_score,
  7. pv.S3_time
  8. FROM (
  9. SELECT id,
  10. SUM(score) AS score,
  11. SUM(time) AS time
  12. FROM my_table
  13. GROUP BY id
  14. )
  15. PIVOT (
  16. SUM(score) AS score,
  17. SUM(time) AS time
  18. FOR コード IN (
  19. 's1' AS S1,
  20. 's2' AS S2,
  21. 's3' AS S3
  22. )
  23. ) pv
  24. S1_score S1_time S2_score S2_time S3_score S3_time
  25. -------------- ---------------- -------------- --------------- --------------- ---------------
  26. 784 355 720 360 260 165

まとめ

SQLのPIVOTの使い方を解説しました。

PIVOTは行列変換ができる便利な機能です。

SQLは少し複雑になりますが、ぜひこの記事を参考にPIVOTをマスターしてください!

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。