sql中col = null查不到数据,因为null是缺失值标记而非值,参与比较时恒返回unknown;必须用col is null判断空值,且is null在多数数据库中可走索引,而coalesce会引发计算开销并可能使索引失效。

WHERE条件里写 col = NULL 为什么查不到数据
因为 SQL 中 NULL 不是值,而是“缺失值”的标记,它不参与任何等于比较——col = NULL 永远返回 UNKNOWN,而 WHERE 只接受 TRUE 的行。
实操建议:
- 必须用
col IS NULL判断是否为空,这是唯一标准写法 -
col != NULL或col NULL同样无效,得写成col IS NOT NULL - 如果列上有索引,
IS NULL在多数数据库(如 PostgreSQL、MySQL 8.0+)中可走索引;但 SQLite 默认不优化该谓词,需确认执行计划
用 COALESCE 或 IS NULL 做条件分支时性能差异大吗
差异明显:直接用 IS NULL 是轻量级布尔判断,而 COALESCE(col, 'default') 会触发表达式计算和类型转换,还可能让优化器放弃索引。
实操建议:
- 仅当真需要“把 NULL 转成某值再比较”时才用
COALESCE,比如WHERE COALESCE(status, 'pending') = 'pending' - 想过滤出 NULL 行,别绕路写
WHERE COALESCE(col, '') = '',这既慢又不可读 - PostgreSQL 支持
col IS NULL索引扫描;MySQL 对函数索引支持有限,COALESCE(col, ...)很难命中索引
在 JOIN 条件里写 ON a.id = b.ref_id 会自动跳过 NULL 匹配吗
会。JOIN 的等值条件是严格比较,NULL = NULL 不成立,所以两边任意一端为 NULL 就不会匹配上——哪怕你期望它们“算作相同”。
实操建议:
- 若业务逻辑中 NULL 应视为同一类(例如未填的客户分类),需显式补充 OR 条件:
ON (a.category = b.category) OR (a.category IS NULL AND b.category IS NULL) - 某些数据库(如 PostgreSQL)支持
IS NOT DISTINCT FROM,可简化写成a.category IS NOT DISTINCT FROM b.category,语义清晰且可优化 - LEFT JOIN 后用
WHERE b.id IS NULL查“没关联上的记录”是常见需求,注意别误写成WHERE b.id = NULL
ORDER BY 里 NULL 排在哪?不同数据库默认行为不一致
是的。SQL 标准规定 NULLS FIRST / NULLS LAST 才明确控制顺序,但各数据库默认不同:PostgreSQL 默认 NULLS LAST,MySQL 和 SQL Server 默认把 NULL 当最小值排最前。
实操建议:
- 只要排序结果影响业务展示或分页,就必须显式声明:
ORDER BY created_at DESC NULLS LAST - MySQL 8.0+ 支持
NULLS FIRST/LAST,但低版本只能靠IF(IS NULL, 1, 0)伪列绕行,性能差 - 在分页场景(如
LIMIT 10 OFFSET 20)中,NULL 位置不稳定会导致同一页反复出现/丢失记录
NULL 的本质不是“空字符串”也不是“零”,它是三值逻辑里的独立状态。很多线上问题都卡在开发者下意识把它当普通值处理——比如在 WHERE、JOIN、ORDER BY、聚合函数里漏掉显式判断,或者依赖数据库默认行为却不验证。










