Query Go
条件分岐で値を作る - CASE 式 の使い方・オプション・サンプル

条件分岐で値を作る - CASE 式

SQL の条件分岐。簡易 CASE と検索 CASE、SELECT / WHERE / ORDER BY / 集約と組み合わせた活用法

概念図

CASE 式 diagram

構文

sql
CASE WHEN 条件 THEN 値 [WHEN ...] [ELSE 値] END

サンプル

金額によってランクラベルを付ける検索 CASE の典型例

sql
SELECT id, amount,
  CASE
    WHEN amount >= 10000 THEN 'high'
    WHEN amount >= 1000  THEN 'mid'
    ELSE 'low'
  END AS tier
FROM orders;

CASE 式とは

CASE は SQL における if / switch に相当するです。文ではなく式なので、値が欲しいところならどこにでも書けます(SELECT、WHERE、ORDER BY、GROUP BY、ON、集約関数の中など)。

形は 2 種類あります。

  • 簡易 CASE: CASE 列 WHEN 値1 THEN ... WHEN 値2 THEN ... END — 等値比較限定
  • 検索 CASE: CASE WHEN 条件 THEN ... WHEN 条件 THEN ... END — 任意の真偽式

WHERE / ORDER BY での活用

複雑な優先度順に並べたい、条件によってソートキーを変えたい、といった場面で CASE が活躍します。

sql
-- ステータスを「進行中 → 未着手 → 完了」の順に並べる
SELECT id, title, status
FROM tasks
ORDER BY CASE status
           WHEN 'in_progress' THEN 1
           WHEN 'todo'        THEN 2
           WHEN 'done'        THEN 3
         END,
         created_at DESC;

集約関数と CASE: 条件付きカウント

SUM(CASE WHEN ... THEN 1 ELSE 0 END)COUNT(CASE WHEN ... THEN 1 END) は条件付きカウントの定番です。ピボットテーブル風の集計にも使えます。

sql
SELECT
  COUNT(*) AS total,
  SUM(CASE WHEN status = 'paid'   THEN 1 ELSE 0 END) AS paid_count,
  SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) AS failed_count
FROM orders;

落とし穴: 型と NULL

  • 全 WHEN / ELSE の戻り値型が揃わないとエラーになる(暗黙変換される RDBMS もあるが頼らない)
  • ELSE 省略時、どの条件にもマッチしないと結果は NULL になる。意図したデフォルトがあるなら必ず書く
  • 簡易 CASE は WHEN NULL THEN ... にマッチしない(NULL = NULL が UNKNOWN のため)。NULL 分岐が欲しいときは検索 CASE で WHEN col IS NULL を使う

関連トピック