NULLの扱い方

このレッスンで分かること

  • NULL は「値がない」状態、NULL = NULLUNKNOWN= では判定できません
  • 判定は IS NULL / IS NOT NULL、代替値は COALESCE(値, 既定値)
  • 最小例は SELECT * FROM users WHERE phone IS NULL; / AVG(COALESCE(point, 0))

NULLの扱い方 とは

データが存在しない場合に用いられるNULLの扱い方について学習します。本レッスンでは、NULLの扱い方 の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

なぜ重要か

データベースを扱っていると必ず登場するのが NULL です。NULL は「値がない」「未入力」「未確定」を表す特別な値で、数値の 0 や空文字列とはまったく別物として扱われます。たとえばユーザの「電話番号」が NULL なら「番号を持っていない」ではなく「まだ登録していない」ことを意味するかもしれません。NULL の扱いを誤ると、集計値がずれたり、WHERE 条件で意図せず行が消えたり、ビジネスロジックがバグだらけになります。

このレッスンでは NULL の比較ルール、IS NULL / IS NOT NULLCOALESCE / IFNULL / NULLIF を使った代替値の埋め方、集計関数での NULL の挙動を整理します。SQL の落とし穴の半分はここに集中していると言っても過言ではありません。

NULL は「0」でも「空文字」でもなく「まだ値が決まっていない」という状態です。この 1 点を取り違えると、集計も WHERE 条件も静かにずれていきます。

NULL の比較は常に UNKNOWN

SQL で NULL と何かを比較すると結果は TRUE でも FALSE でもなく UNKNOWN になります。

SQL クエリ

SELECT (NULL = NULL) AS a, (NULL <> 1) AS b, (NULL = 1) AS c; -- a, b, c すべて NULL (UNKNOWN) になる

だから NULL を判定するには IS NULL または IS NOT NULL を使う必要があります。

SQL クエリ

SELECT * FROM users WHERE phone IS NULL;

等号 = で書いた WHERE phone = NULL誰の行にも当てはまらない ので 0 件が返ります。これが初心者の最大の落とし穴です。

結果用途
col = NULL常に UNKNOWN (false 扱い)NG
col IS NULLtrue / falseNULL 判定
col IS NOT NULLtrue / false非 NULL 判定
COALESCE(col, 0)col か 0表示・計算用代替値
IFNULL(col, 0)col か 0 (MySQL)同上 (2 引数版)
NULLIF(a, b)a (≠b) か NULL0 除算回避

代替値を埋める COALESCE と IFNULL

表示や計算のときに NULL を別の値に置き換えたい場合、COALESCE を使います。

SQL クエリ

SELECT name, COALESCE(phone, '未登録') AS phone_display, COALESCE(point, 0) AS point_safe FROM users;

COALESCE(a, b, c) は左から順に見て、最初に NULL でない値を返します。MySQL / PGlite なら 2 引数版の IFNULL(a, b) も使えます。NULLIF(a, b) は逆で「a と b が等しいときに NULL を返す」関数で、ゼロ除算回避などに使います。

NULL を含む集計の流れ

集計関数で NULL がどう扱われるかを 1 枚にまとめます。

diagram (will load when visible)

要点は次のとおりです。

  • COUNT(*) は NULL も含む全行を数える
  • COUNT(列) / SUM / AVG / MAX / MIN は NULL を完全に無視
  • 平均は NULL でない件数で割られるので、母集団を意識する

代表例 1 NULL を 0 として平均を取る

顧客テーブルにポイント残高 point があり、未登録ユーザは NULL になっているとします。「全員 0 として扱った平均」を取りたいときは次のように書きます。

SQL クエリ

SELECT AVG(COALESCE(point, 0)) AS avg_point FROM users;

COALESCE で NULL を 0 に変換してから平均を取るので、未登録ユーザも分母に含まれます。仕様によって「未登録は除外したい」場合は何もせず AVG(point) で OK です。要件をしっかり確認してから書きましょう。

代表例 2 IS NULL で未登録ユーザを抽出

SQL クエリ

SELECT id, name FROM users WHERE phone IS NULL ORDER BY id;

このクエリは電話番号が未登録のユーザだけを取り出します。SaaS のオンボーディング率を測るときによく使うパターンです。

NULL の判定は必ず IS NULL / IS NOT NULL を使う。等号 = では絶対に判定できません。

三値論理と落とし穴

SQL は TRUE / FALSE / UNKNOWN の三値論理で動きます。WHERE 句では UNKNOWNFALSE 扱いになるので、WHERE col <> 'X' のような条件は col が NULL の行も落としてしまう 点に注意です。

SQL クエリ

-- 'X' 以外を出したいつもりでも、NULL の行は含まれない SELECT * FROM items WHERE category <> 'X'; -- NULL も含めたいなら明示的に書く SELECT * FROM items WHERE category <> 'X' OR category IS NULL;

「数値の 0 と NULL は別物」「空文字と NULL も別物」。データ品質を守るうえで、この区別は最初に身につけたい考え方です。

この章のポイント

ここまでの要点 NULL は「値が決まっていない」状態。判定は IS NULL / IS NOT NULL、代替値は COALESCE。集計関数は NULL を無視 (COUNT(*) は例外)。<> は NULL を落とすので必要なら OR col IS NULL

まとめ

  • NULL = NULL は TRUE ではなく UNKNOWN
  • 判定は IS NULL / IS NOT NULL
  • 代替値は COALESCE(a, b, ...) または IFNULL(a, b)
  • 集計関数は NULL を無視するため、母集団に注意
  • WHERE col <> 'X' は NULL を落とすので、必要なら OR で補う

次のレッスン

次は 算術演算とエイリアス です。SQLでの算術演算と、結果を見やすくするエイリアスの使い方を、SQL操作を通して実践的に学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. NULL の扱い の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. NULL の扱い とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

テーブル構造

schema.sql

CREATE TABLE users ( id INT PRIMARY KEY, name VARCHAR(30) NOT NULL, phone VARCHAR(20), point INT ); INSERT INTO users (id, name, phone, point) VALUES (1, '田中太郎', '090-1111-2222', 1500), (2, '佐藤花子', NULL, 800), (3, '鈴木一郎', '080-3333-4444', NULL), (4, '高橋美咲', NULL, NULL), (5, '伊藤健太', '070-5555-6666', 500);

期待される出力

idname
2佐藤花子
4高橋美咲

ヒント

query.sql
query.sql
学習モード
コードの実行結果
データベースを初期化中...