結論 【IS NOT NULL と <>
の取り扱いに注意】
-
IS NULL
/IS NOT NULL
は NULL に対してのみ使う。 -
<>
(不等号)は 値どうしの比較に使い、NULL には使わない(col <> NULL
は常に不成立=抽出されない)。
サンプルテーブル
CREATE TABLE members (
id INT PRIMARY KEY,
nickname VARCHAR(20), -- NULL を許容
age INT NOT NULL
);
INSERT INTO members (id, nickname, age) VALUES
(1, 'alice', 20),
(2, NULL, 30),
(3, 'guest', 18),
(4, NULL, 40),
(5, 'bob', 25);
出来上がるテーブルは以下の様になる
ここにMD形式のテーブルを簡潔に書く
欲しい結果(例)
「ニックネームが NULL ではなく、かつ 'guest' ではない行」を取りたい。
期待される行:(1, 'alice', 20)
と(5, 'bob', 25)
の2件。
やってはいけない書き方
-- 1) IS の後ろに値('guest')を置く:構文エラー
SELECT * FROM members
WHERE nickname IS NOT 'guest'; -- ❌
-- 2) NULL を <> で比較する:常に不成立(UNKNOWN)
SELECT * FROM members
WHERE nickname <> NULL; -- ❌ (どの行もヒットしない)
-
IS ~ / IS NOT ~
は 後ろにNULL
(※一部DBでは TRUE/FALSE/UNKNOWN などの論理値)しか置けない。 -
NULL
は 値ではなく 「不明」 を表すので、=
,<>
などの通常比較に入れると比較結果は UNKNOWN となり、WHERE
では 落ちる(抽出されない)。
※エラーメッセージの文言はDB製品で異なりますが、上記はどの主要RDBMSでも原理は同じです。
正しい書き方
-- ニックネームがNULLでなく、かつ 'guest' 以外
SELECT * FROM members
WHERE nickname IS NOT NULL
AND nickname <> 'guest';
用途別の最小パターン
-- NULL だけ取りたい
WHERE nickname IS NULL;
-- NULL 以外を取りたい
WHERE nickname IS NOT NULL;
-- 'guest' 以外(※NULLは落ちることに注意)
WHERE nickname <> 'guest';
「
'guest'
以外 かつ NULL も除外したい」なら
WHERE nickname IS NOT NULL AND nickname <> 'guest'
の 二条件にする。
初学者がはまるよくある落とし穴(挙動の再確認)
-
nickname <> 'guest'
だけだと、nickname IS NULL
の行は ヒットしない(「'guest' ではない」とは評価されない)。 -
col = NULL
/col <> NULL
は どちらも使わない。必ずIS NULL
/IS NOT NULL
を使う。
参考
- PostgreSQL ドキュメント:比較演算子と三値論理(NULL を含む比較は UNKNOWN) 。 (PostgreSQL)
- MySQL ドキュメント:
NULL
の扱いとIS NULL
/IS NOT NULL
の使用。 (MySQL Developer Zone) -
IS [NOT] DISTINCT FROM
(NULL セーフな比較)の概要。 (modern-sql.com, Microsoft Learn)
まとめ【間違いやすいポイント】
-
IS NOT '文字列'
のように IS の後ろへ値を置くのは誤り。 -
<> NULL
は 常に不成立。NULL の有無で絞るときは IS 系、値の比較は<>
等正しく比較演算子を使い分ける。