CASE — 条件で値を切り替える

上級123

CASE 式で値をランク分けし、SUM(CASE WHEN ...) の条件付き集計で「条件に合う行だけ数える」書き方を練習します。

CASE 式とは

CASE は SQL の中で 「もし〜なら〜」 を書くための式です。 プログラミング言語の

if / switch にあたるもので、 値が入るところなら どこにでも 置けます。

CASE
  WHEN 条件1 THEN 値1
  WHEN 条件2 THEN 値2
  ELSE 値3
END

上から順に条件を見て、 最初に当てはまった THEN の値を返します。 どれにも

当てはまらなければ ELSE の値です。 ELSE を書かないと NULL になります。

値をランク分けする

数値をそのまま並べるより、 意味のあるラベルに変えたほうが読めることがあります。

SELECT
  name,
  price,
  CASE
    WHEN price >= 30000 THEN '高価格'
    WHEN price >= 5000  THEN '中価格'
    ELSE '低価格'
  END AS price_band
FROM products;

上から順に評価される のが大事なところです。 98000 円は 1 つ目の条件で

すでに当てはまるので、 2 つ目以降は見に行きません。 だから条件は

厳しいほうから順に 並べます。 逆にすると全部が 「中価格」 になります。

条件付き集計 — CASE と集計関数を組み合わせる

CASE の本領はここです。 「カテゴリごとの件数」 と 「そのうち高価格が何件か」 を

1 回のクエリで同時に 出せます。

SELECT
  category,
  COUNT(*) AS total,
  SUM(CASE WHEN price >= 30000 THEN 1 ELSE 0 END) AS high_count
FROM products
GROUP BY category;

条件に合う行だけ 1、 合わない行は 0 を返し、 それを SUM で足す。 これで

「条件に合った行数」 になります。 WHERE で絞ってしまうと 全体の件数が

数えられなくなるので、 並べて比べたいときは WHERE ではなく CASE です。

同じ考え方で 「条件に合う行の合計金額」 も出せます。

SUM(CASE WHEN category = '電子機器' THEN price ELSE 0 END)

よくあるつまずき

- END を忘れる — CASE は必ず END で閉じます。 WHEN が何個あっても END は 1 つです。

- 条件の順番を逆にする — ゆるい条件を先に書くと、 厳しい条件に永久に到達しません。

- ELSE 0 を書き忘れる — 条件付き集計で ELSE を省くと NULL になり、 SUM では

無視されるので結果は同じですが、 COUNT を使うと NULL も数えてしまい ズレます。

条件付き集計は SUM + ELSE 0 で書くのが安全です。

実務での使いどころ

売上表を 「今期 / 前期」 の 2 列に分けて並べる、 アンケート結果を 年代別に

まとめる、 ステータスコードを日本語ラベルに直す — どれも CASE です。

集計しながら分類したい場面は 想像以上に多く、 覚えると クエリの本数が減ります。

次のレッスン: ウィンドウ関数 — 順位を付ける

データベースを初期化中...
SQL エディタCtrl+Enter で実行
SQL を入力して実行してください
練習問題 — 0/3 完了 (0/80pt)
products の name と price に加えて、price が 30000 以上なら '高価格'、5000 以上なら '中価格'、それ以外は '低価格' となる price_band 列を CASE で作り、price の高い順に並べてください。
25pt
カテゴリごとに、商品の総数 total と、price が 30000 以上の商品数 high_count を、条件付き集計 (SUM + CASE) で同時に取得してください。
30pt
products の name と stock に加えて、stock が 20 未満なら '要補充'、100 未満なら '通常'、それ以外は '潤沢' となる stock_level 列を作り、stock の少ない順に並べてください。
25pt