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

関数 ⑤ — CASE で多条件の分岐表示

SQL の関数記事 5 本目です。CASE 式の 2 つの書き方(値マッチ形式と評価式形式)、3 つ以上の分岐、関数や複合条件、ORDER BY との組み合わせまで、CSV の社員データで動かしながら学べます。

本記事で使うデータ — staff テーブル

前回扱った IIF は条件式が 1 つだけ で、真と偽の 2 値分岐しかできませんでした。本記事の CASE 式3 つ以上の条件 を順に評価して、それぞれに違う値を返せます。SQL の中で「if-elseif-else」を書くための基本構文で、レポートのカテゴリ分け・地域分け・成績ランク分けなど、実務でもっとも頻出する分岐構文です。

題材は前回までと同じ staff テーブル(10 行)です。city 列で地域分類、salary 列で給与帯分類、birthday 列で世代分類を作る演習を通して、CASE の 2 つの書き方と複合条件への応用を順に試します。

演習に入る前に、staff テーブルの 列定義データのサンプル を確認しておきます。

PRAGMA table_info(staff); で列名・型・主キーを確認してください。

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

SQL エディタ

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

CASE には 2 つの書き方がある

CASE 式には 値マッチ形式評価式形式 の 2 通りの書き方があり、どちらも同じ結果を作れます。両方に共通するルールが 2 つあります。

  • 最後の `END` が必須 — 書き忘れると構文エラーになります。
  • `ELSE` は省略可能 — 省略するとどの WHEN にも一致しない行が NULL になります。NULL を避けたいときは ELSE でデフォルト値を明示します。

書き方 ① 値マッチ形式 — 列の値を等価比較する

値マッチ形式は CASE 列 WHEN 値1 THEN 結果1 WHEN 値2 THEN 結果2 ... ELSE デフォルト END と書きます。CASE の直後に 比較したい列を 1 つ 置き、WHEN の右には その列と等しいか調べる値 を書きます。判定は 等価比較(`=`)だけWHEN の右に書けるのは 1 つの値だけ で、WHEN ('Tokyo', 'Osaka') のような複数指定はできません。列 = 値 の単純な置き換えに向き、書き方が短くなります。

値マッチ形式の分岐
対象の列WHEN の値返る値CASE city= 'Tokyo'= 'Osaka'ELSE'東京''大阪'もとの city
CASE city が 1 つの列を見て、各 WHEN の値と 等価比較 します。一致した WHENTHEN の値が返り、どれにも一致しなければ ELSE の値になります。
-- 値マッチ形式 — city を地方名に置き換える
SELECT name, city,
  CASE city
    WHEN 'Tokyo' THEN '関東'
    WHEN 'Yokohama' THEN '関東'
    WHEN 'Osaka' THEN '関西'
    WHEN 'Kyoto' THEN '関西'
    ELSE 'その他'
  END AS region
FROM staff;

「社員一覧の city 列を日本語表記に置き換えて表示したい」という要件を想定します。(正しく実行できれば解説が表示されます)

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

値マッチ形式の `CASE` を使い、city が Tokyo なら東京、Osaka なら大阪、Kyoto なら京都、Yokohama なら横浜、Sapporo なら札幌、どれにも当てはまらない場合はもとの city の値、となる列を city_jp という別名で 3 列目に追加してください。

SQL エディタ

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

書き方 ② 評価式形式 — 条件式を自由に書く

評価式形式は CASE WHEN 評価式1 THEN 結果1 WHEN 評価式2 THEN 結果2 ... ELSE デフォルト END と書きます。CASE の直後には 何も書かず、各 WHEN の右に 条件式そのもの を置きます。salary >= 6000000比較演算子name LIKE '%Tanaka'LIKEINAND / OR複合条件 など、WHERE に書ける条件はそのまま使えます。WHEN上から順に評価 され、最初に TRUE になった分岐 で値が確定します。表現力が高いため、実務ではこちらを主に使います。

評価式形式の分岐 — 上から順に評価
WHEN を上から評価判定返る値salary >= 6000000salary >= 4500000ELSETRUE ならTRUE なら残り全部'シニア''中堅''若手'FALSEFALSE
WHEN上から順に評価 します。条件が TRUE になったらその THEN の値で確定し、以降は評価しません。FALSE のときは次の WHEN へ下がり、どれも FALSE なら ELSE の値になります。
-- 評価式形式 — salary を 2 段階に分ける
SELECT name, salary,
  CASE
    WHEN salary >= 5000000 THEN '高め'
    ELSE '標準'
  END AS pay_band
FROM staff;

「給料に応じて社員を 3 段階(若手 / 中堅 / シニア)に分類したい」という要件を想定します。

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

評価式形式の `CASE` を使い、salary が 6,000,000 以上なら 'シニア'、4,500,000 以上 6,000,000 未満なら '中堅'、それ未満なら '若手' となるラベル列を tier という別名で 3 列目に追加してください。

SQL エディタ

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

関数や複合条件と組み合わせて、より複雑な分岐

CASE の WHEN 句には 比較演算子・LIKE・IN・AND / OR・関数呼び出し を組み合わせた評価式を書けます。関数 ① の日付関数で学んだ strftime('%Y', birthday) で生まれ年を取り出して 世代分類 したり、name は『名 姓』の並びなので name LIKE '%Tanaka'(後方一致)で 苗字が Tanaka の人を分類 したり、AND複数列を組み合わせた条件 を書いたりできます。

下の例では、生まれ年を 10 年単位で取り出し、1990 年代生まれを 'Z 世代'、1980 年代生まれを 'X/Y 世代' のようにラベル付けします。strftime の戻り値は文字列なので、比較も文字列リテラル('1990' / '1999')と行います。

-- 1) 生まれ年を 5 年区切りでラベル付け
SELECT name, birthday,
  CASE
    WHEN strftime('%Y', birthday) BETWEEN '1985' AND '1989' THEN '1980 年代後半'
    WHEN strftime('%Y', birthday) BETWEEN '1990' AND '1994' THEN '1990 年代前半'
    ELSE 'その他'
  END AS cohort
FROM staff;

-- 2) 複合条件: 高給かつ Tokyo 在住
SELECT name, city, salary,
  CASE
    WHEN salary >= 6000000 AND city = 'Tokyo' THEN 'Tokyo シニア'
    WHEN salary >= 6000000 THEN 'シニア'
    ELSE 'その他'
  END AS tag
FROM staff;

「全社員を生まれ年で 10 年単位の世代に分けて表示したい」という要件を想定します。

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

評価式形式の `CASE` を使い、birthday から取り出した生まれ年が 1990 年代なら 'Z 世代'、1980 年代なら 'X/Y 世代'、それ以外は 'その他' となるラベル列を generation という別名で 3 列目に追加してください。

SQL エディタ

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

「ランキング画面に給料 TOP 5 を表示し、それぞれに給与帯ラベルを併記したい」という要件を想定します。

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

評価式形式の `CASE` で、実践 2 と同じ給与帯ラベル(salary が 6,000,000 以上で 'シニア'、4,500,000 以上で '中堅'、それ未満で '若手')を tier という別名で 3 列目に追加してください。

`salary` の降順 で並べ、先頭 5 行 に絞ってください。

SQL エディタ

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

理解度チェック

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

Q1次のうち、CASE 式の構造として正しいものはどれですか。

Q2値マッチ形式 CASE city WHEN 'Tokyo' THEN '東京' WHEN 'Osaka' THEN '大阪' ELSE city END の説明として正しいものはどれですか。

Q3CASE WHEN salary >= 6000000 THEN 'シニア' WHEN salary >= 4500000 THEN '中堅' ELSE '若手' END を salary = 7,000,000 の行に対して評価したときの結果はどれですか。