クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

ROLLUPとCUBEで小計と合計

このレッスンのあとで: 1つのクエリで、いくつかの段階の合計を出せる。

55分のレッスンコマンドなし

小計と総合計を、1つのクエリで出す

ROLLUP と CUBE は、小計と総合計を1つの SQL でまとめて出す、GROUP BY の拡張です。

報告書の表の下に付く「小計」や「合計」の行を、手で足さずに出せます。

さらに FILTER を使うと、商品を横に並べた表も作れます。

このレッスンのゴール

メモ

1つのクエリで、いくつかの段階の合計を出せる。

重要な言葉

ことばいみれい
小計1つのグループだけの合計東日本の合計
総合計全部の行の合計
ROLLUP左の列から順に小計を作り、最後に総合計を付ける指定
CUBE列のすべての組み合わせの合計を作る指定
FILTER集計関数に、条件に合う行だけを渡す書き方
ピボット縦に並んだ種類を、横の列に並べ替えた表

学生が入力するセルは、このプレビューでは空白です。

ROLLUP は、小計と総合計を付けてくれる

group by rollup (region, product) と書くと、3つの段階の合計が出ます。地域と商品の組み合わせ、地域ごとの小計、そして総合計です。

合計の行では、まとめた列が NULL になります。NULL は「その列について全部を足した」という印です。

例: rollup の結果

regionproducttotal何の合計か
東日本弁当420000東日本の弁当
東日本NULL660000東日本の小計
西日本NULL670000西日本の小計
NULLNULL1330000総合計

学生が入力するセルは、このプレビューでは空白です。

試す: 小計と総合計

コード: duckdb
-- 地域と商品ごとの売上に、地域の小計と総合計を付けます。
select region, product, sum(amount) as total
from region_sales
group by rollup (region, product)
order by region nulls last, product nulls last;
-- 結果の NULL は、「その列についての合計」を表します。

CUBE は、すべての組み合わせの合計を出す

rollup は左の列から順に小計を作ります。cube は、商品ごとの合計も作ります。地域の組み合わせが全部そろいます。

grouping(列) は、その行が、その列についての合計なら 1 を返します。データに本物の NULL があっても、これで見分けられます。

試す: cube と grouping

コード: duckdb
-- cube は、列のすべての組み合わせの合計を出します。
-- grouping は、その行が合計の行なら 1 を返します。
select region, product, sum(amount) as total,
       grouping(region) as g_region,
       grouping(product) as g_product
from region_sales
group by cube (region, product)
order by region nulls last, product nulls last;

例: rollup と cube の違い

指定出る段階の数(列が2つ)出る合計
group by region, product1地域と商品の組み合わせだけ
group by rollup (region, product)3組み合わせ、地域の小計、総合計
group by cube (region, product)4組み合わせ、地域の小計、商品の小計、総合計

学生が入力するセルは、このプレビューでは空白です。

FILTER で、条件に合う行だけを足す

sum(amount) filter (where product = '弁当') は、弁当の行だけを足します。列ごとに条件を変えて並べると、ピボットの表になります。

種類が少ないときは、この手作りの形が一番分かりやすいです。

試す: 商品を横に並べる

コード: duckdb
-- filter を使って、商品を横に並べた表を手で作ります。
select region,
       sum(amount) filter (where product = '弁当') as bento,
       sum(amount) filter (where product = '飲み物') as drinks,
       sum(amount) as total
from region_sales
group by region
order by region;

よくある間違い

注意

結果の NULL を、データが欠けているのだと読み違えることがあります。本物の NULL が表にあるときは、grouping() で合計の行を見分けましょう。

さらに挑戦

rollup (area, channel) と rollup (channel, area) は、同じ結果になりますか。小計の行がどう変わるかを、考えてから実行して確かめましょう。

そのあと、NULL の代わりに「全体」という文字を表示するには、coalesce をどう使えばよいか考えてください。

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。