必须用is null而非= null,因null是未知标记,= null恒返回unknown(where仅保留true),且is not null不等价于“有业务内容”,空字符串、0等需额外判断。

WHERE 条件里必须用 IS NULL,不能用 = NULL
直接写 WHERE col = NULL 永远查不到任何数据——这不是数据库 bug,而是 SQL 三值逻辑的硬性规则:= 运算符遇到 NULL 时返回 UNKNOWN,而 WHERE 只保留 TRUE 行。
常见错误现象:
- 执行
SELECT * FROM users WHERE email = NULL,结果为空,但实际有大量未填邮箱的记录 - 误以为
!= NULL能查非空值,同样无效
正确写法只有一种:WHERE col IS NULL 或 WHERE col IS NOT NULL。所有主流数据库(MySQL、PostgreSQL、SQL Server、Oracle)都严格支持,无需适配。
IS NOT NULL 不等于 “有内容”,它只排除 NULL
IS NOT NULL 筛出来的字段,可能仍是空字符串 ''、全空格 ' '、数字 0 或日期 '0000-00-00'——这些都不是 NULL,但业务上常被视为“空”。
若需一并过滤,得手动补条件:
- 字符串字段:
WHERE col IS NULL OR TRIM(col) = ''(注意:PostgreSQL/MySQL 支持TRIM();SQL Server 需写RTRIM(LTRIM(col)) = '';Oracle 用TRIM(col)) - 数值字段慎加
OR col = 0——0 很可能是合法业务值(如库存为 0),不能一概而论 - 想查“真正有值”的字符串,推荐
WHERE TRIM(col) != '',它自动跳过NULL和纯空白(因TRIM(NULL)返回NULL,NULL != ''仍为UNKNOWN,不匹配)
COALESCE 和 CASE 适合 SELECT 中处理 NULL,不是 WHERE 替代方案
COALESCE(col, '缺省') 是最简方式把 NULL 转成可读值,比嵌套 CASE WHEN col IS NULL THEN ... 更紧凑。但要注意类型一致性:
-
COALESCE(int_col, 'N/A')在 PostgreSQL 或 SQL Server 中会报错(类型冲突),MySQL 可能隐式转成字符串,但不可靠 - 需要分类统计(比如区分
NULL、''、有效值),只能靠CASE多重判断:CASE WHEN col IS NULL THEN '未填写' WHEN TRIM(col) = '' THEN '空白' ELSE '有效' END
别试图在 WHERE 里用 COALESCE 判断空值——它无法替代 IS NULL 的语义精度,且可能让索引失效。
JOIN 和 GROUP BY 里的 NULL 容易被忽略
IS NULL 只解决查询过滤,但 NULL 在关联和分组中行为更隐蔽:
-
JOIN ON a.id = b.id:任一侧为NULL,整行被丢弃(因为NULL = NULL是FALSE);想让NULL匹配NULL,得写ON (a.id = b.id) OR (a.id IS NULL AND b.id IS NULL) -
GROUP BY col:所有NULL自动归为同一组,这是标准行为,但容易误判为“数据异常” -
ORDER BY col:NULL默认排最前(PostgreSQL)或最后(MySQL),要用ORDER BY col IS NULL, col显式控制顺序
这些地方不报错,但结果不符合直觉——问题往往出在没意识到 NULL 在不同上下文里的语义差异。










