ビジネス分析やダッシュボード設計では、効率的で柔軟な集計処理が求められます。本章では、ロールアップ・キューブといった多次元集計から、GROUPING SETS・PIVOTによるデータの見せ方、そしてスライディングウィンドウによる時系列分析まで、SQL集計の最適化テクニックを解説します。
ロールアップ / キューブ集計
複数の集計軸で、階層的な小計・合計を出したい場合に役立つのが、ROLLUP や CUBE です。
ROLLUP(ロールアップ)
例: 部門ごと+全体の売上合計を出力
SELECT department, product, SUM(amount) FROM sales GROUP BY ROLLUP (department, product);
出力結果:
- 各部署・商品別の売上
- 各部署の合計
- 全体の合計
CUBE(キューブ)
例: 部門 × 商品のすべての組み合わせの集計+合計
SELECT department, product, SUM(amount) FROM sales GROUP BY CUBE (department, product);
キューブは全ての軸で合計を取るため、OLAP(多次元分析)に適しています。
GROUPING関数の活用
NULLが出力される小計/合計行に対して、GROUPING()を使えば識別できます。
SELECT department, product, GROUPING(department) AS g_dep, GROUPING(product) AS g_prod, SUM(amount) FROM sales GROUP BY ROLLUP(department, product);
GROUPING SETS / PIVOT / UNPIVOT
GROUPING SETS
自由な組み合わせで複数の集計パターンを指定できます。ROLLUP/CUBEの上位互換とも言えます。
SELECT department, product, SUM(amount) FROM sales GROUP BY GROUPING SETS ( (department, product), (department), () );
→ 上記は ROLLUP(department, product) と同じ動作
PIVOT(ピボット)
行データを列に展開し、クロス集計を実現するのが PIVOT です。
SQL Serverの例:
SELECT * FROM ( SELECT department, month, amount FROM sales ) AS src PIVOT ( SUM(amount) FOR month IN ([2025-01], [2025-02], [2025-03]) ) AS p;
UNPIVOT(アンピボット)
逆に、列を行に変換するのが UNPIVOT。レポートの元データを正規化する際などに使います。
SQL Serverの例:
SELECT department, month, amount FROM ( SELECT department, [2025-01], [2025-02] FROM sales_summary ) p UNPIVOT ( amount FOR month IN ([2025-01], [2025-02]) ) AS unpvt;
注意: PostgreSQLやMySQLではPIVOT/UNPIVOTはサポートされていないため、CASE文 + GROUP BYやCROSS JOIN等で代替可能です。
スライディングウィンドウ分析(時系列での変化把握)
スライディングウィンドウ分析は、直近n日間の平均や、前回値との差分など、時系列における傾向把握に使われます。
1. 移動平均(Moving Average)
SELECT sale_date, product_id, SUM(amount) OVER ( PARTITION BY product_id ORDER BY sale_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW ) AS moving_sum_7d FROM sales;
→ 各商品ごとに過去7日間の売上合計を算出(ウィンドウフレーム)
2. 前日比(差分)を出す
SELECT sale_date, product_id, amount, amount - LAG(amount) OVER (PARTITION BY product_id ORDER BY sale_date) AS diff FROM sales;
LAG() や LEAD() は、前後の行との比較を可能にするウィンドウ関数です。
3. 累積合計(Cumulative Sum)
SELECT sale_date, product_id, SUM(amount) OVER ( PARTITION BY product_id ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS cumulative_total FROM sales;
売上の成長曲線や、在庫残量の追跡にも有効です。
まとめ
集計パフォーマンスと柔軟性を両立するには、以下のような高度な集計技術を活用するのが有効です。
- ROLLUP / CUBE / GROUPING SETS で多次元分析
- PIVOT / UNPIVOT でデータの形を自在に整形
- ウィンドウ関数 で時系列データの変化を可視化
これらの集計最適化テクニックは、単なるSQL力にとどまらず、分析設計やBIレポートの品質向上にも直結します。