WHERE条件中= NULL永远不成立,必须用IS NULL判断,因为NULL是缺失标记而非值,= NULL返回UNKNOWN被WHERE过滤;正确写法仅有email IS NULL和email IS NOT NULL。

WHERE条件里写= NULL查不到任何数据,必须改用IS NULL
这是最常踩的坑:你明明知道某列全是空的,但SELECT * FROM users WHERE email = NULL返回零行。原因不是数据没存进去,而是SQL标准规定——NULL不参与任何等值比较,= NULL永远返回UNKNOWN,而WHERE只保留TRUE结果。
正确写法只有两个:email IS NULL和email IS NOT NULL。它们是谓词(predicate),不是函数,所以不能加括号、不能带等号。
- ✅ 正确:
WHERE updated_at IS NULL - ❌ 错误:
WHERE updated_at = IS NULL(多写了=) - ❌ 错误:
WHERE IS NULL(updated_at)(误当函数调用) - ❌ 错误:
WHERE email IN (NULL)(IN对NULL无效,整条条件判为UNKNOWN)
IS NULL在LEFT JOIN后找“缺失关联”的记录最常用
比如查“没下过订单的用户”,靠LEFT JOIN + IS NULL是最直接的方式:
SELECT u.name FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE o.user_id IS NULL;
这里关键点是:左连接后,没匹配上的o.user_id自动变成NULL,所以用IS NULL就能精准抓出这些行。
- 别用
o.user_id = NULL,它永远不成立 - 如果连接字段本身允许
NULL(比如orders.user_id设了DEFAULT NULL),那IS NULL仍有效;但如果该字段是NOT NULL,那IS NULL就永远不命中——得先确认表结构 - 大表上高频执行这类查询时,建议给
orders.user_id建索引,部分数据库(如PostgreSQL)能利用索引加速IS NULL扫描
把IS NULL和COALESCE组合用,比方言函数更稳
需要把NULL转成默认值(比如'N/A'或0)时,优先选COALESCE而不是IFNULL、ISNULL()或NVL:
SELECT name, COALESCE(email, '无邮箱') AS email_display FROM users WHERE email IS NULL;
COALESCE是SQL标准函数,所有主流数据库都支持,且行为一致;而ISNULL()在SQL Server和MySQL里语义不同,IFNULL()只在MySQL可用。
-
COALESCE(a, b, c)返回第一个非NULL的值,遇到NULL就跳过,不会报错 - 别用嵌套
CASE WHEN email IS NULL THEN 'N/A' ELSE email END——写起来啰嗦,可读性差 - 注意:
COALESCE所有参数类型需兼容,比如COALESCE(price, 'N/A')在严格模式下可能报类型错误,应统一为字符串或显式转换
区分NULL和空字符串'',否则查询逻辑会错乱
IS NULL只匹配真正未赋值或显式设为NULL的行;而= ''只匹配存了空字符串的行。这两者物理存储、语义、索引行为全都不一样。
比如用户注册时没填地址,后端可能存NULL,也可能存''。如果只写WHERE address IS NULL,漏掉存了''的记录;只写WHERE address = '',又漏掉NULL的。
- 要同时查两者,必须显式写出:
WHERE address IS NULL OR address = '' - 建表时尽量约定策略:业务上“未填写”统一存
NULL,避免混用;或用NOT NULL DEFAULT ''从源头堵死NULL -
COUNT(address)会忽略NULL但计入'',SUM/AVG遇到NULL直接跳过,遇到''则可能因类型转换报错
实际写查询前,先SELECT DISTINCT address, LENGTH(address) FROM users LIMIT 10看看真实数据分布,比凭经验猜更可靠。

















