IS NULL 是唯一可靠判断字段是否为 NULL 的方式,因 NULL 表示未知,不能用 = 或 != 比较;IS NOT NULL 仅排除 NULL,不保证内容有效;NULL、''、0、FALSE 语义完全不同,需严格区分。

IS NULL 判断字段是否为 NULL 值
IS NULL 是 SQL 中唯一可靠判断字段值是否为 NULL 的方式。因为 NULL 表示“未知”,不是值,所以不能用 = 或 != 比较——column = NULL 永远返回 UNKNOWN(在 WHERE 中等价于 FALSE),查不到任何结果。
- 用
WHERE column IS NULL才能命中真正为NULL的行 -
WHERE column = ''只匹配空字符串,和NULL完全无关 - 字符串、数字、日期字段都适用,语法一致,不因类型变化
- 在索引列上使用
IS NULL通常能走索引(取决于数据库和索引定义,MySQL 5.7+、PostgreSQL、SQL Server 均支持)
SELECT * FROM users WHERE email IS NULL;
IS NOT NULL 排除 NULL 值但不等于“有内容”
IS NOT NULL 筛出非 NULL 的行,但它不保证字段有意义:空字符串 ''、全空格、零值 0、默认时间 '0001-01-01' 都算“非 NULL”,但业务上可能仍是无效数据。
- 若需排除“空内容”,得组合判断,比如:
WHERE email IS NOT NULL AND TRIM(email) != '' -
NOT (column IS NULL)语义等价,但可读性差,不推荐 - 某些 ORM(如 Django ORM)生成的
__isnull=False底层就是IS NOT NULL,要注意它不自动过滤空字符串 - PostgreSQL 对
IS NOT NULL优化较好;MySQL 在 MyISAM 引擎下对IS NOT NULL的索引使用略保守(InnoDB 无此问题)
别把 NULL 和空字符串、零值混为一谈
这是最常踩的坑:数据库里 NULL、''、0、FALSE 是四个独立状态,语义完全不同。
- 插入时显式写
NULL(不赋值或写NULL)才存为NULL;多数 ORM 默认不设值即为NULL,但有些框架(如 Laravel Eloquent)会把空表单转成''或0 -
COALESCE(column, 'N/A')能把NULL转成默认值,但对''无效——得先用NULLIF(column, '')把空字符串转成NULL再处理 - 聚合函数如
COUNT(column)自动忽略NULL,但不会忽略''或0 - ORDER BY 中,
NULL默认排最前(ASC)或最后(DESC),行为因数据库而异(PostgreSQL 可用NULLS FIRST/LAST显式控制)
WHERE 中混合 NULL 判断时注意逻辑短路失效
SQL 标准不保证布尔表达式短路,尤其涉及 OR 和 AND 时,NULL 可能让整个条件不可预测。
-
WHERE status = 'active' OR other_col IS NULL:如果status是NULL,左边为UNKNOWN,整体结果取决于右边,但执行计划可能意外跳过索引 - 更危险的是:
WHERE col != 'X' OR col IS NULL——本意是“不是 X 或为空”,但col != 'X'在col为NULL时是UNKNOWN,不触发 OR 的真值传播,实际漏掉NULL行 - 安全写法是显式拆开:
WHERE col IS NULL OR col != 'X' - 复杂条件建议用
CASE WHEN或提前用COALESCE归一化,比堆IS NULL更可控
NULL 的语义是“缺失值”,不是“未初始化”也不是“默认值”。一旦表设计没明确区分 NULL 和空字符串,后续所有查询、统计、导出都容易出偏差——这点在迁移旧系统或对接第三方数据时最容易被忽略。

















