← ブログ一覧に戻る
NULLの扱い方完全ガイド(IS NULL・COALESCE・3値論理)

NULLの扱い方完全ガイド(IS NULL・COALESCE・3値論理)

NULLとは何か

NULLは「0」でも「空文字」でもなく、「値が存在しない・不明である」ことを表す特別な状態です。SQLを学び始めた人がもっともつまずきやすい概念のひとつで、直感に反する挙動が多いため、きちんと理解しておく必要があります。

-- 電話番号が未入力のユーザー
SELECT name, phone FROM users WHERE phone IS NULL;

なぜ「NULL = NULL」はTRUEにならないのか

SQL初心者が最初に驚くポイントがこれです。次のクエリを実行しても、phoneがNULLの行は1件も返ってきません。

-- ❌ これではNULLの行を取得できない
SELECT * FROM users WHERE phone = NULL;

これはSQLが「不明 = 不明」を評価するとき、「両方とも分からないのだから、等しいかどうかも分からない」という3値論理(TRUE / FALSE / UNKNOWN)で動くためです。NULLとの比較は常にUNKNOWN(不明)になり、WHERE句ではUNKNOWNは「条件を満たさない」ものとして扱われます。

正しくNULLを判定する:IS NULL / IS NOT NULL

NULLかどうかを判定するには、=ではなく専用の構文IS NULL / IS NOT NULLを使います。

-- 電話番号が未登録
SELECT * FROM users WHERE phone IS NULL;

-- 電話番号が登録済み
SELECT * FROM users WHERE phone IS NOT NULL;

NULLの練習問題もSQLLearnで用意しています

実際に手を動かしてNULLの挙動を確かめると、理解がぐっと深まります。登録不要・無料ですぐ試せます。

無料で今すぐ練習する →

COALESCEでNULLを別の値に置き換える

NULLをそのまま表示したくない場合は、COALESCE関数で代わりの値を指定できます。COALESCEは引数を左から順に見て、最初にNULLでない値を返します。

-- 電話番号が未登録なら「未登録」と表示する
SELECT name, COALESCE(phone, '未登録') AS phone
FROM users;

-- 複数候補から最初に見つかった値を使う
SELECT COALESCE(nickname, name, '名無しさん') AS display_name
FROM users;

集計関数とNULL:COUNT(*)とCOUNT(column)の違い

集計関数を使うときもNULLの扱いには注意が必要です。

-- テーブルの全行数(NULLも含めて数える)
SELECT COUNT(*) FROM users;

-- phoneがNULLでない行だけを数える
SELECT COUNT(phone) FROM users;

COUNT(*)は行そのものの数を数えるのに対し、COUNT(カラム名)はそのカラムがNULLでない値の数だけを数えます。この違いを知らないと、集計結果が想定と合わずに混乱する原因になります。同様にSUMAVGもNULLの行は計算対象から自動的に除外されます。

WHERE句のNOT INに潜むNULLの罠

NOT INとNULLの組み合わせは、SQLでもっとも有名な落とし穴のひとつです。

-- サブクエリの結果に1件でもNULLが含まれていると…
SELECT * FROM products
WHERE category NOT IN (SELECT category FROM excluded_categories);
-- excluded_categories.category に NULL が1件でもあると
-- このクエリは0件しか返さなくなる(意図せず全滅する)

NOT INのリストにNULLが混ざると、内部的に「不明なものと比較して等しくないと言い切れるか?」という判定がUNKNOWNになり、結果的に行が一切マッチしなくなります。NOT INを使う際は、対象のカラムにNULLが含まれていないか事前に確認するか、NOT EXISTSを使う方が安全です。

ORDER BYでNULLはどこに並ぶか

NULLを含むカラムで並び替えると、データベースによってNULLが先頭にくるか末尾にくるかが異なります。明示的に制御したい場合は次のように書けます。

-- NULLを末尾にまとめる(PostgreSQLの場合)
SELECT * FROM users ORDER BY phone NULLS LAST;

-- NULLを先頭にまとめる
SELECT * FROM users ORDER BY phone NULLS FIRST;

まとめ

  • NULLは「不明・存在しない」を表す特別な値で、0や空文字とは別物
  • NULL = NULLはTRUEにならない(3値論理のため)
  • NULL判定にはIS NULL / IS NOT NULLを使う
  • COALESCEでNULLを代わりの値に置き換えられる
  • COUNT(*)COUNT(カラム名)は挙動が異なる
  • NOT INにNULLが混ざると結果が0件になる罠がある(NOT EXISTSが安全)
  • ORDER BY ... NULLS LAST/FIRSTでNULLの並び順を制御できる

NULLの罠、実際に踏んでみて覚えよう

SQLLearnにはNULLの挙動を体感できる練習問題があります。無料・登録不要で今すぐ試せます。

無料で今すぐ練習する →