Q1次のうち、ORDER BY CASE WHEN city = 'Tokyo' THEN 1 WHEN city = 'Osaka' THEN 2 ELSE 9 END の説明として正しいものはどれですか。
関数 ⑥ — CASE 応用 — ORDER BY / UPDATE / NULL 対応
SQL の関数記事 6 本目です。ORDER BY CASE で任意順序を割り当てる書き方、UPDATE 〜 SET 列 = CASE での条件付き一括更新、CASE と NULL の扱いを CSV の社員・顧客データで学べます。
本記事で使うデータ — staff と customer
前回まで学んだ CASE は SELECT の列リストに置くだけでなく、`ORDER BY` の中・`UPDATE` の SET 句にも書ける汎用的な式です。本記事ではこれら 2 つの応用と、CASE で NULL を扱うときの落とし穴 を順に押さえます。
題材は前半が staff テーブル(社員 10 名)、後半が customer テーブル(顧客 8 名 / NULL を含む)です。前半は city を任意順序に並び替え、後半は email の NULL を「未登録」と表示する CASE、最後に country の値を地域カテゴリに書き換える UPDATE CASE を実行します。
ORDER BY で CASE を使う — 任意の順序を割り当てる
ORDER BY の右辺には 列名だけでなく、CASE 式も書けます。これを使うと、文字列のアルファベット順や数値の大小では作れない 任意の順序 を割り当てられます。「東京 → 大阪 → 京都 → その他」のような業務上の優先順位、「未対応 → 対応中 → 完了」のようなステータス順、ランクの並び順を表現したいときに使います。
書き方は ORDER BY CASE WHEN 条件 THEN 数値 ... ELSE 数値 END のように、CASE で 並び順用の数値 を返し、その数値で並べ替えます。ASC(昇順)/ DESC(降順)も列と同じように付けられます。同じ数値の行は、続く ORDER BY の 2 番目の列(カンマ区切り)で並ぶので、並び順 + 副キー を組み合わせてカテゴリ内の順序も決められます。
-- 1) city を「Osaka → Kyoto → Tokyo → その他」の順で並べる
SELECT name, city, salary FROM staff
ORDER BY
CASE city
WHEN 'Osaka' THEN 1
WHEN 'Kyoto' THEN 2
WHEN 'Tokyo' THEN 3
ELSE 9
END,
salary DESC; -- 同じ city 内は給料の高い順
-- 2) ORDER BY CASE + DESC で逆順にもできる
-- CASE で 1, 2, 3 と割り当てたなら DESC で 3, 2, 1 の順になる
CASE と NULL の落とし穴 — `= NULL` ではなく `IS NULL` を使う
WHERE と同じく、CASE の中でも `= NULL` / `<> NULL` は使えません。NULL との比較結果は常に NULL(不明)になり、CASE の WHEN 句が NULL を返すと その分岐は採用されない ため、結果が想定と違ってしまいます。
NULL を判定するときは `列 IS NULL` / `列 IS NOT NULL` を使います。これは前に学んだ WHERE の NULL 判定と同じルールで、CASE / IIF / WHERE / ON など、条件式が書ける場所すべてで共通 です。値マッチ形式(CASE 列 WHEN ... THEN)では NULL 判定はできないので、NULL を扱いたいときは必ず 評価式形式(CASE WHEN 列 IS NULL THEN ...)を使います。
-- 誤: WHEN NULL では NULL 行を取り出せない('不明' が表示されない)
SELECT name, age,
CASE age
WHEN NULL THEN '不明'
ELSE age
END AS age_display
FROM customer;
-- 正: 評価式形式 + IS NULL
SELECT name, age,
CASE
WHEN age IS NULL THEN '不明'
ELSE age
END AS age_display
FROM customer;
-- 注: COALESCE(age, '不明') でも同じ結果になる
-- 2 値の単純な NULL 置換なら COALESCE の方が簡潔
UPDATE で CASE を使う — 条件に応じて値を書き換える
ここまでは CASE で 新しい列を読み取り側で生成 していましたが、UPDATE の SET 句に CASE を書くと、テーブル本体の列の値を条件に応じて書き換える ことができます。
書き方は UPDATE 表 SET 列 = CASE WHEN 条件 THEN 値1 WHEN 条件 THEN 値2 ... ELSE 列 END です。ELSE 列 で「どの WHEN にも当てはまらない行は元の値のまま」と書くのが安全な書き方で、これを忘れると ELSE が NULL 扱いになって対象外の行が NULL で上書きされます。
UPDATE は テーブル本体を変更する破壊的な操作 なので、本記事では 最後の演習 で扱います。実行前に同じ条件で SELECT name, 列, CASE ... を試して結果を目視確認し、想定通りなら UPDATE に書き換えるのが本番運用での基本動作です。
-- まず SELECT で結果を確認(NULL の age を 0 にする想定)
SELECT name, age,
CASE
WHEN age IS NULL THEN 0
ELSE age
END AS new_age
FROM customer;
-- 想定どおりなら UPDATE に書き換え
UPDATE customer SET age = CASE
WHEN age IS NULL THEN 0
ELSE age
END;
理解度チェック
まずは1問ずつ答えてみましょう。
Q2次のうち、CASE で NULL を扱う 正しい書き方 はどれですか。
Q3UPDATE customer SET country = CASE WHEN country IN ('Japan') THEN 'Asia' WHEN country IS NULL THEN 'Unknown' ELSE country END; で `ELSE country` を書く理由として最も正しいものはどれですか。