順番に読み進めながら学べます

関数 ⑥ — 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 を実行します。

演習に入る前に、本記事で使う 2 つのテーブル — staffcustomer — の 列定義データのサンプル を確認しておきます。

PRAGMA table_info(staff);PRAGMA table_info(customer); で両テーブルの列定義を確認してください。

SELECT * FROM staff LIMIT 5;SELECT * FROM customer LIMIT 5; で先頭 5 行のデータをプレビューしてください。

SQL エディタ

クエリを実行してください

ORDER BY で CASE を使う — 任意の順序を割り当てる

ORDER BY の右辺には 列名だけでなく、CASE 式も書けます。これを使うと、文字列のアルファベット順や数値の大小では作れない 任意の順序 を割り当てられます。「東京 → 大阪 → 京都 → その他」のような業務上の優先順位、「未対応 → 対応中 → 完了」のようなステータス順、ランクの並び順を表現したいときに使います。

書き方は ORDER BY CASE WHEN 条件 THEN 数値 ... ELSE 数値 END のように、CASE で 並び順用の数値 を返し、その数値で並べ替えます。ASC(昇順)/ DESC(降順)も列と同じように付けられます。同じ数値の行は、続く ORDER BY の 2 番目の列(カンマ区切り)で並ぶので、並び順 + 副キー を組み合わせてカテゴリ内の順序も決められます。

ORDER BY CASE — 任意の順序を割り当てる
cityCASE で割り当てる数値並び順Tokyo11 番目Osaka22 番目Kyoto33 番目それ以外9 (ELSE)最後
CASE で「Tokyo なら 1、Osaka なら 2、…」のように並び順用の数値を返し、その数値で ORDER BY します。文字列順では作れない任意のカテゴリ順を表現できます。
-- 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 の順になる

「拠点規模の大きい順(Tokyo → Osaka → Kyoto → その他)に社員を表示したい」という要件を想定します。(正しく実行できれば解説が表示されます)

staff テーブルから namecity の 2 列を取り出してください。

ORDER BY CASE で「Tokyo は 1、Osaka は 2、Kyoto は 3、それ以外は 9」を割り当て、その数値で並べてください。同じ city 内は 名前の昇順 で並べる多段ソートにしてください。

SQL エディタ

クエリを実行してください

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 ...)を使います。

CASE で NULL を扱う書き方
誤った書き方正しい書き方CASE name WHEN NULL THEN '不明' ELSE nameENDCASE WHEN name IS NULL THEN '不明' ELSE nameENDWHEN NULL は常に不一致 → '不明' が出ないIS NULL でNULL を正しく判定できる
値マッチ形式では NULL を直接 WHEN に書けません。NULL を扱うときは評価式形式に切り替えて、IS NULL / IS NOT NULL を使います。
-- 誤: 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 の方が簡潔

「顧客一覧画面で email 列の NULL を '未登録' と表記して、空白の代わりに表示したい」という要件を想定します。

customer テーブルから nameemail を取り出してください。

評価式形式の `CASE` を使い、email が NULL の行は '未登録'、そうでない行は元の email の値、となる列を email_display という別名で 3 列目に追加してください。

SQL エディタ

クエリを実行してください

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;

「顧客テーブルの country 列を、国名から地域カテゴリ(Asia / Western / Europe / Unknown)に一括変換したい」という要件を想定します。本記事の最後の演習なので、テーブル本体を 書き換える破壊的な操作 を行います。

customer テーブルの country 列を CASE で一括 UPDATE してください。マッピングは:

- Japan → Asia

- US または UK → Western

- Italy → Europe

- NULL → Unknown

- それ以外 → もとの値のまま(再実行しても結果が変わらないようにする)

② UPDATE のあとに SELECT id, name, country FROM customer ORDER BY id; を実行し、各顧客の country が地域名に変わっていることを確認してください。

SQL エディタ

クエリを実行してください
QUIZ

理解度チェック

まずは1問ずつ答えてみましょう。

Q1次のうち、ORDER BY CASE WHEN city = 'Tokyo' THEN 1 WHEN city = 'Osaka' THEN 2 ELSE 9 END の説明として正しいものはどれですか。

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` を書く理由として最も正しいものはどれですか。