null = null 不是 true,因为 null 表示未知而非值,两个未知无法比较相等;where col = null 永不匹配,必须用 is null;not in 遇 null 整体失效,应改用 not exists 或排除 null。

NULL = NULL 为什么不是 TRUE
因为 NULL 在 SQL 里不是值,而是“未知”这个状态的标记。两个未知的东西,你没法断定它们相等——就像问“张三的离职日期是未知,李四的离职日期也是未知,他俩是不是同一天离职?”,数据库只能回答“不知道”,而不是“是”或“否”。
WHERE col = NULL 永远查不到数据
WHERE 子句只保留条件结果为 TRUE 的行。col = NULL 不管 col 实际是不是 NULL,结果永远是 UNKNOWN,被直接过滤掉。
-
WHERE quit_date = NULL→ 0 行返回,哪怕表里真有quit_date为NULL的记录 -
WHERE quit_date IS NULL→ 正确写法,明确检测缺失状态,返回对应行 - 注意:
= NULL语法合法,不报错,但逻辑上永远失效
NOT IN 遇到 NULL 就全崩
当子查询或列表中包含 NULL,NOT IN 整体表达式会退化为 UNKNOWN,导致整条 WHERE 条件失效,结果集为空。
-
SELECT * FROM orders WHERE status NOT IN ('shipped', 'canceled', NULL)→ 查不到任何数据 - 根本原因:
'pending' NOT IN ('shipped', 'canceled', NULL)等价于NOT ('pending' = 'shipped' OR 'pending' = 'canceled' OR 'pending' = NULL),最后一项'pending' = NULL是UNKNOWN,整个 OR 结果变成UNKNOWN,NOT 后仍是UNKNOWN - 替代方案:用
NOT EXISTS或先过滤掉NULL,比如status NOT IN (SELECT status FROM ... WHERE status IS NOT NULL)
IS NULL 是唯一可靠的空值谓词
IS NULL 和 IS NOT NULL 是 SQL 标准定义的真值测试谓词,不参与值比较,不触发三值逻辑传染。它们直接检查字段是否处于“缺失”状态,返回确定的 TRUE 或 FALSE。
-
name = ''判断空字符串,name IS NULL判断完全缺失,二者语义不同,不能混用 -
COALESCE(col, 'default')可用于把NULL转成具体值,但判断阶段仍必须用IS NULL - 聚合函数如
COUNT(col)默认忽略NULL,但COUNT(*)统计所有行——这点也常被忽略
复杂点在于,这种三值逻辑不会报错,也不会警告,它只是静默丢掉数据。你查不到结果时,第一反应不该是“数据没了”,而该看条件里有没有碰到了 NULL。










