SQL Academy · レッスン

小計のためのROLLUP

小計と総計を集計します。

レッスン 2/413 ステップ

「小計のためのROLLUP」はCoddyKit上の無料SQL Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Academyコースには全4レッスンが含まれています。

ROLLUPとは

GROUP BYでデータをグループ化すると、グループごとに1行が得られます。しかし、多くの場合は各グループの小計や、すべての行を対象とした総計も必要になります。それを実現するのがROLLUPです。

ROLLUPはGROUP BYの拡張機能で、結果セットに追加の集計行を自動的に加えます。これにより、グループ化階層の各レベルで小計が得られ、最後に総計が追加されます。

サンプルデータの準備

練習用に、シンプルなsalesテーブルを作成しましょう。このテーブルには、各取引の地域、商品カテゴリ、売上金額を保存します。以下のステートメントを実行して、テーブルを作成し、データを入力してください。

CREATE TABLE sales (
  region   TEXT,
  category TEXT,
  amount   NUMERIC
);

INSERT INTO sales VALUES
  ('East',  'Electronics', 500),
  ('East',  'Electronics', 300),
  ('East',  'Clothing',    150),
  ('West',  'Electronics', 700),
  ('West',  'Clothing',    200),
  ('West',  'Clothing',    100);

まずは通常のGROUP BY

ROLLUPを使う前に、通常のGROUP BYで何が得られるかを確認しましょう。以下のクエリは、(region, category)の組み合わせごとに1つの合計を返します。小計も総計もありません。

SELECT region, category, SUM(amount) AS total
FROM   sales
GROUP  BY region, category
ORDER  BY region, category;

GROUP BY ROLLUPの概要

GROUP BYをGROUP BY ROLLUP(...)に置き換えると、SQLが小計行を自動的に追加します。ROLLUP()内の列が階層を構成し、その階層の各レベルに対する小計と、最後の総計が生成されます。

SELECT region, category, SUM(amount) AS total
FROM   sales
GROUP  BY ROLLUP(region, category)
ORDER  BY region, category;

ROLLUPの出力を読み取る

ROLLUPの結果には、次の3種類の行が含まれます。

  • 詳細行 — 通常のGROUP BYと同様に、(region, category)の組み合わせごとに1行が表示されます。
  • 小計行 — 地域ごとに1行が表示され、category = NULLとなります。その地域の合計を示します。
  • 総計行 — regionとcategoryの両方がNULLとなる行が1行表示され、全体の合計を示します。

NULLは、集計されたレベルを示すプレースホルダーとして機能します。

COALESCEでNULLにラベルを付ける

NULLのマーカーは、エンドユーザーには分かりにくいことがあります。各列をCOALESCEで囲み、'すべてのカテゴリ'や'総計'のような意味のあるラベルに置き換えましょう。

SELECT
  COALESCE(region,   'Grand Total')    AS region,
  COALESCE(category, 'All Categories') AS category,
  SUM(amount)                          AS total
FROM   sales
GROUP  BY ROLLUP(region, category)
ORDER  BY region, category;

1列のROLLUP

ROLLUPは1列だけでも使用できます。ROLLUP(region)と記述すると、地域ごとに1行が表示され、その末尾に総計行が1行追加されます。これは最もシンプルな形式で、詳細行の下に累計を表示したいレポートに便利です。

SELECT
  COALESCE(region, 'Grand Total') AS region,
  SUM(amount)                     AS total
FROM   sales
GROUP  BY ROLLUP(region)
ORDER  BY region;

3レベルのROLLUP

ROLLUPに3列以上を渡すと、より深い階層を構築できます。ROLLUP(year, region, category)を指定すると、年と地域ごとの小計、年ごとの小計、総計が得られます。列を1つ追加するたびに、集計のレベルが1つ増えます。

-- Extend the demo with a year column
SELECT
  COALESCE(CAST(yr AS TEXT), 'All Years')     AS year,
  COALESCE(region,   'All Regions')            AS region,
  COALESCE(category, 'All Categories')         AS category,
  SUM(amount)                                  AS total
FROM (
  SELECT 2024 AS yr, region, category, amount FROM sales
  UNION ALL
  SELECT 2025 AS yr, region, category, amount FROM sales
) t
GROUP  BY ROLLUP(yr, region, category)
ORDER  BY yr, region, category;

GROUPING()で集計行を検出する

GROUPING()関数は、その行の列の値がROLLUPによって生成されたNULL(集計用のプレースホルダー)の場合は1を、実際のデータ値の場合は0を返します。これにより、実際のNULLデータと、ROLLUPによる集計のNULLを区別できます。

SELECT
  region,
  category,
  SUM(amount)        AS total,
  GROUPING(region)   AS is_region_summary,
  GROUPING(category) AS is_cat_summary
FROM   sales
GROUP  BY ROLLUP(region, category)
ORDER  BY region, category;

集計行をフィルタリングする

ROLLUPは集計後に行を追加するため、WHEREでそれらをフィルタリングすることはできません。HAVINGを使うか、クエリ全体をサブクエリで囲んでください。以下の例では、地域ごとの小計だけを残します(categoryがROLLUPによるNULLで、regionが実際の値である行です)。

SELECT region, SUM(amount) AS regional_total
FROM   sales
GROUP  BY ROLLUP(region, category)
HAVING GROUPING(category) = 1
   AND GROUPING(region)   = 0
ORDER  BY region;

ROLLUPとGROUPING SETS

ROLLUP(a, b)は、特定のGROUPING SETSを簡潔に記述したものです。以下の2つのクエリは完全に同じ結果になります。ROLLUPを使うと、すべてのグループ化レベルを手動で記述する必要がありません。

-- Using ROLLUP (concise)
SELECT region, category, SUM(amount) AS total
FROM   sales
GROUP  BY ROLLUP(region, category);

-- Equivalent explicit GROUPING SETS
SELECT region, category, SUM(amount) AS total
FROM   sales
GROUP  BY GROUPING SETS(
  (region, category),
  (region),
  ()
);

理解度チェック

この問題でROLLUPについての理解度を確認しましょう。

レッスンの振り返り

よくできました。ROLLUPについて学んだ内容をまとめます。

  • GROUP BY ROLLUP(a, b)は、列の階層の各レベルに対する小計と、すべての行を対象とした総計を自動的に生成します。
  • 集計された列にはNULLが入り、集計行であることが示されます。COALESCEを使うと、読みやすいラベルを付けられます。
  • GROUPING()関数は、ROLLUPによって生成されたNULLに対しては1を、実際のデータ値に対しては0を返すため、両者を区別できます。
  • HAVING GROUPING(...) = 1を使うと、集計行だけに絞り込めます。
  • ROLLUP(a, b)はGROUPING SETS((a, b), (a), ())を簡潔に記述したものです。

複雑なUNIONクエリを書かずに小計と総計をレポートへ追加したい場合、ROLLUPは最適なツールです。

無料で開始

AI チューターと学ぶ SQL — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
46
レッスン
183

よくある質問

「小計のためのROLLUP」レッスンは無料ですか?

はい。「小計のためのROLLUP」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Academyコースには全4レッスンが含まれています。

「小計のためのROLLUP」で何を学びますか?

小計と総計を集計します。 ブラウザで直接実行するハンズオンコードでSQL Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

SQL Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSQL Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「小計のためのROLLUP」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSQL Academyレッスンでコードを書いて実行できますか?

はい。すべてのSQL Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 単一のGROUP BYを超えて
  2. 小計のためのROLLUP
  3. すべての組み合わせのためのCUBE
  4. GROUPING SETSを理解する
← SQL Academyに戻る