NULLの扱い方 — 「値がない」を正しく扱う
SQLのNULL(値がない状態)の意味と扱い方を解説します。IS NULLによる判定、COALESCEでの穴埋め、比較や集約でNULLがどう振る舞うかの落とし穴まで整理します。
データベースを扱っていると必ず出会うのが NULL(ヌル)です。NULL は「値が存在しない・不明である」ことを表す特別な状態で、初学者がつまずきやすいポイントでもあります。0 や空文字('')とは意味が違うことを、まず押さえましょう。
NULL とは何か
NULL は「まだ値が入っていない」「そもそも値が分からない」ことを表します。たとえば会員登録で電話番号を入力しなかった場合、その列は NULL になります。ここで大切なのは、
NULLは 0 ではない(数値のゼロは「0 という値がある」状態)NULLは 空文字''でもない(空文字は「長さ0の文字列という値がある」状態)
NULL は「値がない」こと自体を表す、いわば箱が空っぽの状態です。
NULL の判定は IS NULL
もっとも間違えやすいのが NULL の判定です。次のように書いても、NULL の行は取り出せません。
SELECT name
FROM customers
WHERE phone = NULL;これは一件も返りません。SQL では「NULL と何かを = で比べた結果は、真でも偽でもなく NULL(=不明)」になるためです。「不明なもの」と比較しても結果は「不明」であり、条件を満たしたとは判定されません。
NULL かどうかを調べるには、専用の IS NULL / IS NOT NULL を使います。
SELECT name
FROM customers
WHERE phone IS NULL;「電話番号が登録されていない会員」を正しく取り出せます。登録済みだけを見たいなら IS NOT NULL です。
COALESCE で NULL を置き換える
NULL のままだと表示や計算で困ることがあります。そんなときは COALESCE で別の値に置き換えられます。COALESCE は「引数を左から見て、最初に NULL でない値を返す」関数です。
SELECT name, COALESCE(phone, '未登録') AS phone
FROM customers;電話番号が NULL の行は「未登録」と表示されます。数値でも同様に、NULL を 0 とみなして計算したいときに使えます。
SELECT name, COALESCE(bonus, 0) AS bonus
FROM employees;集約と NULL
集約関数は NULL の扱いに独特のルールがあります。
COUNT(*)は行数を数える(NULL の行も数える)COUNT(列)はその列が NULL でない行だけを数えるSUM/AVG/MAX/MINは NULL を無視して計算する
SELECT
COUNT(*) AS 全行数,
COUNT(phone) AS 電話番号あり,
AVG(bonus) AS 平均ボーナス
FROM employees;ここで AVG(bonus) は、bonus が NULL の人を分母に含めません。「NULL を 0 として平均したい」場合は、先に COALESCE(bonus, 0) で埋めてから平均します。意図と違う結果にならないよう注意が要ります。
NULL の連鎖に注意
NULL を含む計算は、結果も NULL になります。
SELECT price + shipping AS total
FROM orders;shipping が NULL だと、price に値があっても total は NULL になります。加算の前に COALESCE(shipping, 0) で埋めておくのが安全です。
まとめ
- NULL は「値がない」状態で、0 や空文字とは別物
- 判定は
= NULLではなくIS NULL/IS NOT NULL COALESCEで NULL を別の値に置き換えられる- 集約では
COUNT(列)やAVGが NULL を無視する点に注意 - NULL を含む計算は結果も NULL になる
NULL を正しく扱えるかどうかは、SQL の正確さを大きく左右します。「値がないかもしれない」列を扱うときは、常に NULL の可能性を意識するようにしましょう。