CodeGym /コース /SQL SELF /条件式: CASE <式> WHEN ... THEN ... ELSE ... END...

条件式: CASE <式> WHEN ... THEN ... ELSE ... END

SQL SELF
レベル 10 , レッスン 1
使用可能

もしもうCASEに慣れてたら、ロジックを直接クエリに埋め込む方法って知ってるよね。でもCASEには2つの形があるって意外と知られてない。CASE WHEN ...if-elseみたいな条件分岐だけど、シンプルなCASEは他の言語のswitch-caseみたいな感じ:1つの式を複数の値と比べて、合うやつのブロックを実行するんだ。

1つのカラムを固定値と比べる時は、こっちの方がコンパクトで直感的。

シンプルなCASEの構文

CASE expression
    WHEN value1 THEN result1
    WHEN value2 THEN result2
    ...
    ELSE default_result
END

めっちゃシンプル:

  • expression — これは比べる式やカラム。value1value2とかと比べる。
  • THENは一致した時に返すやつ。
  • ELSE — どれも合わなかった時に返すやつ(省略できるけど、入れた方がいい)。

例:学生の成績

studentsテーブルにgradeカラムがあって、2から5までの整数が入ってるとしよう。これをテキストで表示したい時:

SELECT
    name,
    grade,
    CASE grade
        WHEN 5 THEN '優秀'
        WHEN 4 THEN '良い'
        WHEN 3 THEN '可'
        WHEN 2 THEN '不可'
        ELSE '不明'
    END AS 成績_テキスト
FROM students;

ここでCASEgradeカラムの値を2, 3, 4, 5と比べてる。

例:商品カテゴリをコードから表示

productsテーブルのcategory_codeカラムには'el''frn''bks'みたいな短いラベルが入ってる。読みやすいカテゴリ名を表示したい時:

SELECT
    product_name,
    category_code,
    CASE category_code
        WHEN 'el' THEN 'エレクトロニクス'
        WHEN 'frn' THEN '家具'
        WHEN 'bks' THEN '本'
        ELSE 'その他'
    END AS category_name
FROM products;

こういうのは、「人間向け」テキストをコードの代わりに出したい時に超便利。

例:月の名前

月番号からテキストで月名を出したい時:

SELECT
    EXTRACT(MONTH FROM order_date) AS month_number,
    CASE EXTRACT(MONTH FROM order_date)
        WHEN 1 THEN '1月'
        WHEN 2 THEN '2月'
        WHEN 3 THEN '3月'
        WHEN 4 THEN '4月'
        WHEN 5 THEN '5月'
        WHEN 6 THEN '6月'
        WHEN 7 THEN '7月'
        WHEN 8 THEN '8月'
        WHEN 9 THEN '9月'
        WHEN 10 THEN '10月'
        WHEN 11 THEN '11月'
        WHEN 12 THEN '12月'
        ELSE '不明'
    END AS month_name
FROM orders;

シンプルなCASEで、1〜12の数字を一発で分かりやすくできる。

シンプルなCASEでのNULLの扱い

大事なのは、値がNULLと比べられる時、結果はNULLになるってこと。なぜならNULL = NULL真じゃなくて不明だから。

NULLの例:

SELECT
    user_id,
    status,
    CASE status
        WHEN 'active' THEN 'アクティブ'
        WHEN 'blocked' THEN 'ブロック済み'
        WHEN NULL THEN 'ステータスなし'  -- これは効かない!
        ELSE '不明'
    END AS user_state
FROM users;

WHEN NULLの代わりにELSEを使うか、検索型CASE(前回のレクチャーでやったやつ)を使おう:

CASE
    WHEN status IS NULL THEN 'ステータスなし'
    ...

検索型CASEとの比較

特徴 シンプルCASE 検索型CASE
特定の値との比較 ✅ 得意 ❌ 不向き
柔軟な条件(>, IS NULLなど) ❌ 無理 ✅ できる
プログラミングでの類似 switch-case if-else

実用ケース

例:リクエストのステータス可視化

request_id status
101 new
102 in_progress
103 done
104 cancelled
105 NULL
SELECT
    request_id,
    CASE status
        WHEN 'new' THEN '🟡 新規'
        WHEN 'in_progress' THEN '🔵 進行中'
        WHEN 'done' THEN '🟢 完了'
        ELSE '⚪ 不明'
    END AS status_label
FROM requests;
request_id status_label
101 🟡 新規
102 🔵 進行中
103 🟢 完了
104 ⚪ 不明
105 ⚪ 不明

ここでCASEは翻訳者みたいな役割:テクニカルなステータスを分かりやすく(しかも可愛い)ラベルに変換。ステータスが不明やNULLでも、ユーザーには⚪「不明」って出る。

例:レポート用のカテゴリ分け

employee_id name department
1 Alex Lin HR
2 Maria Chi IT
3 Anna Song IT
4 Otto Art FIN
5 Jane Doe HR
6 Max Gray SALES
7 Zoe Black IT
8 Tom Brown FIN
9 Liam Park NULL
10 Eva Gold HR
SELECT
    CASE department
        WHEN 'HR' THEN '人事'
        WHEN 'IT' THEN 'テクノロジー'
        WHEN 'FIN' THEN '財務'
        ELSE 'その他'
    END AS dept_name,
    COUNT(*) AS staff_count
FROM employees
GROUP BY
    CASE department
        WHEN 'HR' THEN '人事'
        WHEN 'IT' THEN 'テクノロジー'
        WHEN 'FIN' THEN '財務'
        ELSE 'その他'
    END;

結果:

dept_name staff_count
人事 3
テクノロジー 3
財務 2
その他 2

何が起きてるかというと:

  • HRの人は「人事」カテゴリに入る。
  • ITは「テクノロジー」。
  • FINは「財務」。
  • それ以外(SALESやNULLも含む)は「その他」。こういうやり方は、フレンドリーで分かりやすいレポート作りにピッタリ。

よくあるミス

  • ELSEを忘れる → どれも一致しなかったらNULLになる。
  • NULLと比較する → 効かないから、IS NULLと検索型CASEを使おう。
  • 型が合わないものを比べる → 例えばgradeが数値型なのにCASE grade WHEN '5'みたいに書く。

シンプルなCASEは、1つの値をいくつかの候補と比べたい時の武器。コンパクトで読みやすくて、テキスト分類や可視化、コード変換、グループ化に超便利。

もし範囲チェックやNULL、もっと複雑な条件が必要なら、検索型CASEを使おう。SQLは分かりやすさが命。CASEは、その分かりやすさを形にするためのツールだよ。

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION