書籍の中でCASE文のメリットを書いている部分があり、GROUP BYのメリットも気になったため調べてみました。
元のテーブル
pref_name | sex | population |
---|---|---|
北海道 | 1 | 2000 |
北海道 | 2 | 2200 |
北海道 | 1 | 3000 |
北海道 | 2 | 3000 |
青森県 | 1 | 1500 |
青森県 | 2 | 1600 |
青森県 | 1 | 1500 |
青森県 | 2 | 1500 |
東京 | 1 | 4000 |
東京 | 2 | 4500 |
東京 | 1 | 4000 |
東京 | 2 | 4000 |
CASE 文を使ったSQL
書籍に書かれていたSQL文は下記でした。
SELECT
pref_name,
-- 男性の人口
SUM(CASE WHEN sex = '1' THEN population ELSE 0 END) AS cnt_m,
-- 女性の人口
SUM(CASE WHEN sex = '2' THEN population ELSE 0 END) AS cnt_f
FROM PopTbl2
GROUP BY pref_name;
出力例
pref_name | cnt_m | cnt_f |
---|---|---|
北海道 | 5000 | 5200 |
青森県 | 3000 | 3100 |
東京 | 8000 | 8500 |
解説:
この形式では、各都道府県の男性人口と女性人口がそれぞれのカラムに出力されます。
データがクロス表形式(横方向に集約)となるため、1行で都道府県ごとの人口分布が確認でき、可読性が高いです。
集計条件を柔軟に指定できるのが CASE 文の強みです(例: 特定の年齢層を条件に加えるなど)。
CASE 文を使わず、GROUP BY だけを使用したSQL
先ほどのSQLをGROUP BYを使って書き換えてみます。
SELECT
pref_name,
sex,
SUM(population) AS cnt
FROM PopTbl2
GROUP BY pref_name, sex;
出力例
pref_name | sex | cnt |
---|---|---|
北海道 | 1 | 5000 |
北海道 | 2 | 5200 |
青森県 | 1 | 3000 |
青森県 | 2 | 3100 |
東京 | 1 | 8000 |
東京 | 2 | 8500 |
解説:
この形式では、都道府県ごとに性別でレコードが分かれる(縦方向に集約)ため、データが冗長になります。
男性人口と女性人口をそれぞれ確認したい場合は、フィルタリングや加工が別途必要です。
両者の違いと用途
比較点 |
CASE を使う場合 |
GROUP BY だけの場合 |
---|---|---|
出力形式 | 横方向(クロス表形式) | 縦方向(性別ごとに分かれる) |
可読性 | 一目で男性と女性の人口が分かる | 性別ごとに確認する必要がある |
柔軟性 | 条件をカラムごとにカスタマイズ可能 | シンプルな集計には適している |
用途 | ダッシュボードやレポートで使いやすい | 明細レベルでのデータ分析に向いている |