为什么 = NULL
永远不成立
因为
NULL在 SQL 中不是值,而是“未知”状态。它不等于任何东西——包括它自己。所以
WHERE col = NULL的结果永远是
UNKNOWN(三值逻辑中的第三种状态),而
WHERE子句只接受
TRUE的行,
UNKNOWN和
FALSE都被过滤掉。
SELECT * FROM users WHERE phone = NULL;→ 返回空结果集,哪怕表里真有
phone为
NULL的记录 同理,
phone != '138xxx'或
phone '138xxx'也不会包含
NULL行——它们被悄悄排除了 这和 Python 的
NaN == NaN返回
False是同一类设计哲学:未知不可比较
正确写法只有 IS NULL
和 IS NOT NULL
这是 SQL 标准语法,在 MySQL、PostgreSQL、SQL Server 等所有主流数据库中都一致有效,且语义明确、无歧义。
查空值:WHERE email IS NULL查非空值:
WHERE email IS NOT NULL可安全组合:
WHERE status = 'active' AND created_at IS NULL注意:
IS是关键字,不能省略或替换成
=;
IS NULL是一个整体操作符,不是 “IS” 加 “NULL”
常见连带陷阱:不等于条件漏掉 NULL 数据
当你写
WHERE score 100,本意可能是“找出所有没得满分的人”,但实际结果里不会包含
score为
NULL的人——他们既没得 100,也不算“不等于 100”,只是“未知”。 要真正表达“不是 100,包括未知”,必须显式补上:
WHERE score 100 OR score IS NULL同理,
IN和
NOT IN对 NULL 敏感:
WHERE id NOT IN (1, 2, NULL)会返回空——因为含
NULL的
NOT IN整体判为
UNKNOWN安全替代方案:
WHERE id NOT IN (1, 2) AND id IS NOT NULL
想显示默认值?别在判断上硬扛,用函数转换
如果只是想让查询结果里不出现
NULL(比如报表展示),与其在
WHERE里反复纠结,不如用转换函数在
SELECT层处理。
IFNULL(email, '未填写')—— MySQL 专用,简洁直接
COALESCE(phone, mobile, '暂无联系方式')—— 标准 SQL,支持多参数取第一个非 NULL 注意:
COALESCE所有参数类型需兼容,否则可能隐式转换出错(如字符串和数字混用)
SELECT name, COALESCE(phone, mobile, '请补充联系方式') AS contact, IFNULL(score, 0) AS score_display FROM students;
NULL 不是空字符串,不是 0,不是 false,它就是“不知道”。只要记住判断它只能靠
IS NULL,显示它优先用
COALESCE,绝大多数坑就绕开了。
