不能用= null判断空值,因为null表示“未知值”,任何与null的比较(如=、!=)均返回unknown,而where只保留true行;必须使用is null/is not null谓词,它们语义明确、跨数据库兼容且能正确筛选。

为什么不能用 = NULL 判断空值
因为 SQL 中的 NULL 表示“未知值”,不是具体数据,它不等于任何东西——包括它自己。所以 WHERE column = NULL 永远返回空结果集,哪怕该列全是 NULL。这是三值逻辑(True/False/Unknown)决定的,= NULL 的比较结果是 Unknown,而 WHERE 只保留 True 的行。
常见错误现象:
- 执行
SELECT * FROM users WHERE email = NULL返回 0 行,但实际有大量未填邮箱的记录 - 用
!= NULL或NULL同样无效,结果一样为空
必须用 IS NULL 和 IS NOT NULL
这两个是 SQL 标准中专门用于判断空值的谓词,语义明确且跨数据库兼容(MySQL、PostgreSQL、SQL Server、Oracle 等均支持)。
实操建议:
- 查空值:写
WHERE column IS NULL,例如SELECT id, name FROM orders WHERE shipped_at IS NULL - 查非空值:写
WHERE column IS NOT NULL,注意它**不等价于WHERE column != ''或WHERE column > 0**,因为字符串空值''和数值0都不是NULL - 在索引字段上使用
IS NULL通常能走索引(取决于数据库和索引类型),但需确认执行计划,例如 PostgreSQL 对 B-tree 索引默认包含NULL值
小心 NULL 在其他上下文中的“隐形陷阱”
即使你记住了 IS NULL,在聚合、连接、条件表达式里仍容易出错:
-
COUNT(column)会自动忽略NULL行,但COUNT(*)不会——别误以为两者等价 -
WHERE col1 = col2在任一列为NULL时整行被跳过,应改用WHERE col1 IS NOT DISTINCT FROM col2(PostgreSQL)或手动补OR (col1 IS NULL AND col2 IS NULL) -
COALESCE(col, 'default')是安全的替代方案,但要注意类型隐式转换,比如COALESCE(int_col, 'N/A')在强类型数据库中会报错
检查表结构时留意默认值是否真设了 NULL
有时你以为某列允许空值,其实建表时写了 NOT NULL DEFAULT '' 或 NOT NULL DEFAULT 0,这时用 IS NULL 永远查不到数据。
快速验证方式:
- MySQL:
SHOW COLUMNS FROM table_name LIKE 'column_name',看Null列是否为YES - PostgreSQL:
\d table_name或查information_schema.columns中的is_nullable - 别只看业务逻辑,得看实际 DDL —— 很多“应该为空”的字段,上线时被开发顺手加了默认值
真正麻烦的不是记不住 IS NULL,而是当查询没结果时,下意识怀疑数据错了,却忘了先查表定义和默认约束。










