用IS NULL判断空值,= NULL永远失效;因NULL是缺失标记,所有等值比较均返回UNKNOWN,WHERE只保留TRUE行。

直接结论:用 IS NULL,别用 = NULL —— 后者永远查不到任何结果。
为什么 = NULL 一定失效
NULL 在 SQL 中不是“一个值”,而是“缺失值”的标记。所有与 NULL 的等值比较(=、!=、<>)都返回 UNKNOWN,而 WHERE 只保留 TRUE 行,UNKNOWN 被直接丢弃。
常见错误现象:
- 写
WHERE email = NULL→ 返回空结果集,哪怕 email 全是 NULL - 写
WHERE status != 'done'→ 会漏掉所有status IS NULL的行,因为NULL != 'done'是UNKNOWN,不进结果
IS NULL 和 IS NOT NULL 的基本用法
这是唯一符合 SQL 标准、跨数据库(MySQL/PostgreSQL/SQL Server/Oracle)通用的空值判断方式。
实操建议:
- 查字段为 NULL 的记录:
SELECT * FROM users WHERE email IS NULL - 查字段非 NULL 的记录:
SELECT * FROM orders WHERE logistics_no IS NOT NULL - 多列同时非空:
WHERE name IS NOT NULL AND phone IS NOT NULL - 注意:
IS NOT NULL不排除空字符串''或纯空格' ',它只管是否为 NULL
业务上常说的“空”往往不止 NULL
比如用户手机号字段,可能存的是 NULL、''、' ',三者在业务逻辑里常被一并视为“未填写”。
实操建议:
- 排除 NULL 和空字符串:
WHERE phone IS NOT NULL AND phone != '' - 再排除空白字符(MySQL/PostgreSQL):
WHERE phone IS NOT NULL AND TRIM(phone) != '' - SQL Server 需写成:
RTRIM(LTRIM(phone)) != '' - SQLite 的
TRIM()不支持多字符裁剪,但基础空格裁剪可用
容易忽略的性能和索引影响
IS NULL 条件本身可以走索引,但效果取决于字段的 NULL 比例和索引类型。
关键点:
- 如果某字段 NULL 占比极高(比如 > 95%),优化器可能放弃走索引,直接全表扫描
- 复合索引中,只有最左前缀字段为
IS NULL时才可能生效;例如索引是(a, b),WHERE a IS NULL AND b = 1一般不走索引 - 想加速高频空值查询,可建函数索引(如 PostgreSQL 的
CREATE INDEX ON t ((col IS NULL)))或在应用层加冗余标记字段
真正麻烦的从来不是语法怎么写,而是你得先想清楚:这个“空”,在业务语义里到底指什么——是没填?填了但删了?还是系统根本没生成该字段?不同含义对应不同的过滤组合,混用就会漏数据或误筛。

















