2025年11月4日火曜日

SQL Server 集計関数の応用と分析テクニック|ROLLUP・CUBE・GROUPING SETSの使い方

SQL Server 集計関数の応用と分析テクニック|ROLLUP・CUBE・GROUPING SETSの使い方

SQL Server では、GROUP BY をさらに拡張して多次元的な集計を行うことができます。
たとえば「地域 × 商品 × 月別売上」のようなクロス集計を1つのSQLで作ることも可能です。
その鍵となるのが ROLLUP・CUBE・GROUPING SETS という3つの拡張構文です。
この記事では、それぞれの仕組みと使い分けを、初心者にも理解できるよう図解感覚で解説します。

目次

GROUP BY拡張構文とは?

基本のGROUP BYをおさらい

通常のGROUP BYでは、指定した列ごとに1段階の集計しか行えません。


SELECT Region, SUM(SalesAmount) AS TotalSales
FROM Sales
GROUP BY Region;

このSQLは「地域別の売上合計」を求めますが、「地域ごとの合計+全体合計」を1回のクエリで出すことはできません。
そこで登場するのが ROLLUP / CUBE / GROUPING SETS です。

ROLLUPの使い方(階層的な集計)

ROLLUPとは

ROLLUP は、指定した列の階層ごとに小計・総計を自動計算する構文です。
「地域 → 店舗」や「年 → 月」といった階層データで特に有効です。


SELECT Region, Store, SUM(SalesAmount) AS TotalSales
FROM Sales
GROUP BY ROLLUP (Region, Store);

この結果には以下のような行が含まれます。

  • 各店舗ごとの売上(Region+Store)
  • 地域単位の合計(Regionのみ)
  • 全体合計(NULL行)

つまり、ROLLUPは「下位→上位→全体」へと階層的に集計を追加してくれる機能です。

実務例:年・月別売上


SELECT YEAR(OrderDate) AS 年,
       MONTH(OrderDate) AS 月,
       SUM(SalesAmount) AS 売上合計
FROM Sales
GROUP BY ROLLUP (YEAR(OrderDate), MONTH(OrderDate))
ORDER BY 年, 月;

このように、ROLLUPを使えば年次・月次集計をまとめて出力できます。

CUBEの使い方(多次元集計)

CUBEとは

CUBE は、指定した列のすべての組み合わせパターンで集計を行います。
たとえば「地域」「商品」の2軸を指定すると、以下のように全パターンの集計が生成されます。


SELECT Region, Product, SUM(SalesAmount) AS TotalSales
FROM Sales
GROUP BY CUBE (Region, Product);

結果には以下が含まれます。

  • 地域×商品別売上
  • 地域別売上
  • 商品別売上
  • 全体売上

つまり、CUBEは「全軸組み合わせの総当たり集計」を生成する仕組みです。
OLAP分析(多次元分析)やレポート出力で活用されます。

GROUPING SETSの使い方(柔軟な集計パターン)

GROUPING SETSとは

GROUPING SETS は、複数のGROUP BY句を1つのSQLでまとめて処理できる機能です。
「年度別」と「担当者別」のような異なる切り口の集計を同時に出したい場合に便利です。


SELECT YEAR(OrderDate) AS 年,
       SalesPerson,
       SUM(SalesAmount) AS 売上合計
FROM Sales
GROUP BY GROUPING SETS (
  (YEAR(OrderDate)),
  (SalesPerson),
  ()
);

この例では、以下3種類の集計が同時に得られます。

  • 年別売上
  • 担当者別売上
  • 全体売上

ROLLUPやCUBEが階層的・網羅的な集計なのに対し、GROUPING SETSは必要な組み合わせだけを指定できる柔軟な形式です。

GROUPING関数で集計行を識別する

GROUPING関数の使い方

ROLLUPやCUBEで出力された結果には、NULLが混在します。
NULLが「本当にデータがない」のか「集計行(小計・総計)」なのかを区別するにはGROUPING関数を使います。


SELECT 
  Region, 
  Product, 
  SUM(SalesAmount) AS TotalSales,
  GROUPING(Region) AS IsRegionTotal,
  GROUPING(Product) AS IsProductTotal
FROM Sales
GROUP BY CUBE (Region, Product);

GROUPING() の戻り値が 1 の場合、その列は集計行(小計・総計)です。
これを利用して、「合計」ラベルを付けることも可能です。


SELECT 
  CASE WHEN GROUPING(Region) = 1 THEN '合計' ELSE Region END AS 地域,
  CASE WHEN GROUPING(Product) = 1 THEN '小計' ELSE Product END AS 商品,
  SUM(SalesAmount) AS 売上合計
FROM Sales
GROUP BY CUBE (Region, Product);

まとめと実務での使い分け

3つの拡張構文の違い

構文 特徴 主な用途
ROLLUP 階層的な集計(小計・総計) 年→月・地域→店舗など階層構造
CUBE 全組み合わせでの多次元集計 分析・レポート・クロス集計
GROUPING SETS 指定した組み合わせだけを集計 複数視点をまとめた柔軟集計

実務でのポイント

  • レポート作成やBI分析ではROLLUPとCUBEが非常に便利。
  • GROUPING関数で「小計/総計」行を識別して整形できる。
  • GROUPING SETSは自由なパターン指定ができるため、分析用途に最適。

参考リンク

SQL Server 解説用イメージ

0 件のコメント:

コメントを投稿