NULLの扱い方
このレッスンで分かること
NULLは「値がない」状態、NULL = NULLはUNKNOWNで=では判定できません- 判定は
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 NULL、COALESCE / 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 NULL | true / false | NULL 判定 |
col IS NOT NULL | true / false | 非 NULL 判定 |
COALESCE(col, 0) | col か 0 | 表示・計算用代替値 |
IFNULL(col, 0) | col か 0 (MySQL) | 同上 (2 引数版) |
NULLIF(a, b) | a (≠b) か NULL | 0 除算回避 |
代替値を埋める 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 枚にまとめます。
要点は次のとおりです。
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 句では UNKNOWN は FALSE 扱いになるので、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 つができることを確認しましょう。
- NULL の扱い の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (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);期待される出力
| id | name |
|---|---|
| 2 | 佐藤花子 |
| 4 | 高橋美咲 |