レック・テクノロジー・コンサルティング株式会社TECH BLOG

【BigQuery】縦持ちデータを横持ちデータに変換するPIVOT演算子

Accessのクロス集計表をBigQueryで実現する要件があり、どうやって実現するか困っていたところ、BigQueryにはPIVOT演算子があることが分かり、無事解決できたのでご紹介します。

PIVOT項目を静的に指定する方法と、動的に指定する方法の2通りについて記述しています。

縦持ちの「店別売上データ」から、"静的"に横持ちの「店別売上データ_PIVOT」に変換 

店CD、店名毎に、期をPIVOT項目として売上げを集計する。

スクリーンショット 2024-11-07 154141.png

PIVOT演算子の文法

FROM
[テーブル or サブクエリ]
PIVOT(
[集約関数] [, ...]
FOR [入力項目]
IN ([PIVOT項目] [, ...])
)

[テーブル or サブクエリ]:PIVOT前のテーブル名、または、サブクエリを記載
[集約関数]:SUMやCOUNT等の集約関数を記載
[入力項目]:列を作る際の元となる項目を記載
[PIVOT項目]:列として出力する項目を記載

SQL

実際にSQLを作成し実行してみます。
今回は総計も出力したいので、サブクエリを使用しました。

CREATE OR REPLACE TABLE `店別売上データ_PIVOT` AS
SELECT
*
FROM
(
SELECT
`店CD`,
`店名`,
SUM(`売上`)OVER(PARTITION BY `店CD`,`店名`) AS `総計`,
`期`,
`売上`
FROM `店別売上データ`
)

PIVOT(
SUM(`売上`) FOR `期` IN (
'Q1','Q2','Q3','Q4'
 )
)
ORDER BY `店CD`
;

実行結果

想定通りの結果が得られました。

スクリーンショット 2024-11-07 154943.png

スクリーンショット 2024-11-07 154959.png

縦持ちの「店別売上データ」から、"動的"に横持ちの「店別売上データ_PIVOT」に変換 

先ほどの例はPIVOT項目が期だったので、Q1からQ4と静的に指定を行えましたが、日付等の可変の項目をPIVOT項目とし、PIVOT変換する方法をご紹介します。
PIVOT項目を可変とするため、データから日付情報を取得し、「EXECUTE IMMEDIATE FORMAT」を利用して実現します。

スクリーンショット 2024-11-07 155500.png

スクリーンショット 2024-11-07 155523.png

SQL

実際にSQLを作成し実行してみます。

---配列定義
DECLARE daily_labels ARRAY<STRING>;

--日付を配列に設定
SET daily_labels = (
 SELECT ARRAY_AGG(i.`日付`)
 FROM (SELECT DISTINCT `日付` FROM `店別売上データ` ORDER BY 1) AS i
);

--配列をUNSET展開しながらIN句に設定する文字列を生成する
EXECUTE IMMEDIATE FORMAT("""
 CREATE OR REPLACE TABLE `店別売上データ_PIVOT` AS
 SELECT
 *
 FROM
 (
 SELECT
 `店CD`,
 `店名`,
 SUM(`売上`)OVER(PARTITION BY `店CD`,`店名`) AS `総計`,
 `日付`,
 `売上`
 FROM `店別売上データ`
 )
 PIVOT(
 SUM(`売上`) FOR `日付` IN %s) ORDER BY `店CD`;
""", (SELECT CONCAT("(",STRING_AGG(CONCAT("'",dailys,"'"),","),")") FROM UNNEST(daily_labels) AS dailys))

実行結果

想定通りの結果が得られました。

スクリーンショット 2024-11-07 160414.png

スクリーンショット 2024-11-07 160430.png

まとめ

今回の要件は、動的に横持ちのテーブルに変換する必要があったため、「PIVOT演算子」と「EXECUTE IMMEDIATE FORMAT」を使用して、無事解決することが出来ました。

また、「PIVOT演算子」と逆で、横持ちを縦持ちに変換する「UNPIVOT演算子」というのもあるらしいので、試してみたいと思います。

この記事をシェアする

  • Facebook
  • X
  • Pocket
  • Line
  • Hatena
  • Linkedin

資料請求・お問い合わせはこちら

ページトップへ戻る