📖 テーマ設定
🔊 音声設定
1.2
1.0
1.0
▶️ 再生コントロール
🎵 BGM設定
0.3
🔔 効果音設定
0.3

NULL値の扱いとCASE式

概要

  • 日程: Day 2 / セッション 5
  • 時間: 11:40-12:00
  • 形式: 座学
  • ゴール: NULLが「未知の値」であり通常の比較で扱えないことと、CASE式による条件分岐の書き方を説明できる
  • 学習形式: 対話型解説

導入(5分)

前のJOIN演習で、LEFT JOIN の結果に NULL が出てきたのを覚えていますか? 「総務部 / 社員なし」の行で、first_name が NULL になっていました。

NULL は SQLの中でとびきり厄介な存在です。なぜなら「0でも空文字でもなく、未知」だからです。「未知」をどう扱うか——これを誤ると、件数がズレたり、フィルタから漏れたりします。

このセッションでは、NULL の正体と、結果を「高・中・低」のように分類する CASE式 を学びます。

本編(15分)

1. NULL は「ゼロ」でも「空文字」でもない

たとえば顧客テーブルに、電話番号未登録の顧客がいるとします。phone 列には何が入るでしょうか?

  • 0 を入れる → 0番という電話番号があることになる(嘘)
  • 空文字 '' を入れる → 「番号は空文字です」という主張(これも嘘)
  • NULL を入れる → 「番号は分からない/未登録」という正直な表明

NULL は「値が分からない、未知である」というマーカーです。

コード例・実例

SELECT customer_name, phone
FROM customers
WHERE phone IS NULL;

ここで気をつけたいのが、phone = NULL と書いてはいけないこと。

-- これは結果が0件になる(意図と違う)
SELECT * FROM customers WHERE phone = NULL;

理由は、「未知 = 未知」が真にならないからです。NULL同士の比較は 常に NULL(不明) という第3の真理値になり、WHERE は TRUE の行しか返さないので、結果から落ちます。

たとえるなら「中身の分からない箱A」と「中身の分からない箱B」を比べて「同じです」と断言できますか? できませんよね。それと同じです。

2. NULL を扱う3兄弟

演算子 意味
IS NULL NULL かどうかを判定
IS NOT NULL NULL でないかを判定
COALESCE(列, 代替値) NULL なら代替値に置き換える

コード例・実例

電話番号が未登録の顧客を抽出:

SELECT customer_name
FROM customers
WHERE phone IS NULL;

未登録なら「未登録」と表示する:

SELECT customer_name, COALESCE(phone, '未登録') AS phone
FROM customers;

ここがポイント

  • = ではなく IS NULL を使う(鉄則)
  • COALESCE は引数を左から見て、最初に NULL でないものを返す
  • COALESCE は何個でも書ける:COALESCE(a, b, c, '不明') のように

コラム — 「NULL同士は等しくない」事件

ある集計バッチで、「同じ商品コードの注文をまとめる」処理を書いた人が、商品コードに NULL が混ざっていたためにグループ化されない問題に遭遇しました。NULL は他のNULLと等しいと見なされないので、GROUP BY product_code で NULL の行が一つずつ別グループになりかけて、集計件数が増えて大慌て。SQLでは「NULL は誰の友達でもない」と覚えてください。

3. CASE式 — SQLの中の if 文

「給与が高い/中/低を判定して表示したい」——これがCASE式の出番です。

コード例・実例

SELECT first_name,
       last_name,
       salary,
       CASE
         WHEN salary >= 500000 THEN '高'
         WHEN salary >= 400000 THEN '中'
         ELSE '低'
       END AS salary_rank
FROM employees;

結果:

first_name last_name salary salary_rank
太郎 山田 450000
花子 鈴木 520000
... ... ... ...

基本構文:

CASE
  WHEN 条件1 THEN 値1
  WHEN 条件2 THEN 値2
  ELSE  デフォルト値
END

ここがポイント

  • 上から順に評価され、最初にマッチした WHEN で確定する
  • ELSE を書かないとマッチしないときに NULL になる
  • 最後に END を忘れない(PostgreSQLの end は予約語的に区切りを意味する)
  • 結果に列名を付けたいときは END AS 列名

4. CASE と NULL の組み合わせワザ

NULL を判定して、結果を分けたいケース。

SELECT customer_name,
       CASE
         WHEN phone IS NULL THEN '未登録'
         ELSE phone
       END AS phone_display
FROM customers;

これは前に出てきた COALESCE(phone, '未登録') と同じ意味です。シンプルな置き換えは COALESCE、複雑な条件分岐は CASE と使い分けます。

💬 AIに聞いてみよう

  • 「NULL を含む列の合計や平均をとると、どう扱われる?」
  • 「CASE と COALESCE はどちらを使うべき?選び方を教えて」
  • CASE salary WHEN 500000 THEN ... のような書き方もあるって本当?」

まとめ(5分)

NULL は「未知」のマーカー。比較には = ではなく IS NULL を使い、置き換えたいときは COALESCE を使う——これだけで、ほとんどのNULLトラブルは避けられます。

CASE式は SQL の中の if 文。CASE WHEN ... THEN ... ELSE ... END の構造を覚えておけば、結果の見た目を整えたり、レポート用の分類を作ったりが自在になります。

flowchart LR A["値"] --> B{"NULL?"} B -->|"はい"| C["IS NULL / COALESCE"] B -->|"いいえ"| D["通常の比較"] A --> E{"複数条件で分類?"} E -->|"はい"| F["CASE WHEN"]

次のセッション(昼休み後)では、これらを使って実際に「給与ランク表示」「電話未登録の顧客抽出」「未登録の見た目を整える」演習を行います。

🔄 振り返りチェック

  • phone = NULLphone IS NULL の違いを説明できますか?
  • COALESCE と CASE の使い分けを言えますか?
  • CASE式の最後に書く END を忘れたら何が起きますか?

補足資料

  • 発展課題: 自分の身の回りで「未入力」をどう表現するか考えてみる(例:申込書の任意欄、SNSのプロフィール)。NULL/空文字/既定値のどれが適切か?

学習ガイド

想定される質問と回答例

質問 ヒント
NULL を含む列を SUM や AVG したら? NULL は計算から除外される。SUM(salary) は NULL を無視して残りを足す。COUNT(*) は NULL も含むが COUNT(列名) は NULL を除外する
WHERE phone <> '03-1234-5678' で NULL の人は出てくる? 出てこない。NULL との比較は NULL になり、TRUE 以外は WHERE から落ちる。「NULL も含めて他」が欲しいなら OR phone IS NULL を足す
COALESCE と NULLIF の違いは? COALESCE はNULLを別の値に置き換える。NULLIF(a, b) は a=b のとき NULL を返す(逆方向の変換)
CASE は WHERE や ORDER BY でも使える? 使える。ORDER BY CASE WHEN status = 'pending' THEN 1 ELSE 2 END のように並び順を制御するのもよくある

つまずきやすいポイント

つまずきポイント ヒント
column = NULL と書いてしまう 必ず IS NULL / IS NOT NULL。プログラミング言語のクセが出やすいので注意
NULL が混じった列で集計件数が合わない COUNT(*) は全行、COUNT(列名) は NULL を除外。意図に合わせて使い分ける
CASE で ELSE を書かず、想定外に NULL になる マッチしないと結果は NULL。ELSE を書く習慣を
CASE の END を書き忘れる/AS の位置を間違える ... ELSE 値 END AS 列名 の順序。END を忘れると構文エラーで止まる
読み上げを開始します...

AIに質問する