IS NULL 是标准且正确的空值判断方式,因为 NULL 不是值而是缺失标记,= NULL 永远返回 UNKNOWN,WHERE 中被过滤;IS NULL 和 IS NOT NULL 是专用于检测 NULL 语义的真值测试谓词。

在 SQL 中,IS NULL 是标准、正确的空值判断方式,而 = NULL 永远返回 UNKNOWN(在 WHERE 或 ON 条件中等效于 FALSE),查不到任何结果——这不是语法错误,而是由 SQL 三值逻辑(TRUE/FALSE/UNKNOWN)决定的本质行为。
NULL 不是值,而是一种“缺失标记”
SQL 中的 NULL 表示“未知”或“不适用”,它不等于任何东西,包括它自己。因此:
-
NULL = NULL的结果不是 TRUE,而是 UNKNOWN -
NULL = 5、NULL = ''、NULL = NULL全部返回 UNKNOWN - WHERE 子句只保留计算结果为 TRUE 的行,自动过滤掉 FALSE 和 UNKNOWN
IS NULL 是专门设计的谓词,用于检测缺失状态
不同于比较运算符(=、!=、> 等),IS NULL 和 IS NOT NULL 是 SQL 标准定义的**真值测试谓词**,直接作用于 NULL 的语义属性:
-
column IS NULL→ 返回 TRUE 当且仅当 column 确实为 NULL -
column IS NOT NULL→ 返回 TRUE 当且仅当 column 有确定的非空值 - 它们不参与值比较,不触发三值逻辑的“传染性”,行为确定可靠
常见误用与实际影响
写 WHERE age = NULL 看似直觉,但实际等价于 WHERE UNKNOWN,整张表被跳过。例如:
- 表 users 有 100 行,其中 3 行 age 为 NULL →
SELECT * FROM users WHERE age = NULL返回 0 行 - 正确写法必须是
SELECT * FROM users WHERE age IS NULL→ 返回那 3 行 - 某些数据库(如 PostgreSQL)会直接拒绝
= NULL并报错;MySQL 和 SQL Server 虽允许,但逻辑不变
扩展:如何安全地处理 NULL 比较
若需逻辑上“把 NULL 当作相同值来对待”(如去重、连接),不能依赖 =,而应使用:
-
IS NOT DISTINCT FROM(标准 SQL,PostgreSQL/SQL Server 支持):可安全比较两个可能为 NULL 的表达式 -
COALESCE(a, 'default') = COALESCE(b, 'default'):将 NULL 映射为统一占位值再比较(注意类型和默认值合理性) - 连接时用
ON a.id = b.id OR (a.id IS NULL AND b.id IS NULL)显式覆盖 NULL 匹配场景









