因null表示未知值,任何等值比较结果均为unknown,where只接受true;而''是确定的零长度字符串,可用=直接匹配。

为什么 '' 和 NULL 在 WHERE 条件里行为完全不同?
SQL 标准里,NULL 表示“未知值”,不参与任何等值比较;而空字符串 '' 是一个确定的、长度为 0 的字符串。所以 WHERE col = NULL 永远不成立,WHERE col = '' 则只匹配空串——但很多人误以为二者可互换。
-
WHERE col IS NULL才能正确筛选出 NULL 值 -
WHERE col = ''只匹配空字符串,对 NULL 无影响 -
WHERE col IN ('', NULL)是无效写法:NULL在IN中会被忽略,实际等价于WHERE col = '' - 某些 ORM(如 Django)或迁移脚本可能把空表单字段存成
''而非NULL,导致后续查询漏数据
如何统一处理:把 '' 和 NULL 都视作“空”?
用 COALESCE 或 NULLIF 配合条件判断最稳妥:
-
WHERE COALESCE(col, '') = '':把NULL转成''后再比,能同时捕获两者 -
WHERE NULLIF(col, '') IS NULL:把空字符串转成NULL,再用IS NULL判断,语义更清晰 - 注意:如果列有索引,
COALESCE(col, '') = ''通常无法走索引;而WHERE col IS NULL OR col = ''在多数数据库中可命中索引(尤其 PostgreSQL、MySQL 8.0+)
INSERT/UPDATE 时怎么避免混入 ''?
业务逻辑层应主动归一化,而非依赖数据库兜底:
- 应用写入前判断:
if value == '' then value = NULL(Python/JS 等语言中注意区分undefined、null、'') - 数据库层面可用默认约束:
col VARCHAR(50) DEFAULT NULL,并禁止NOT NULL且无默认值的空字符串列 - 触发器或生成列(如 PostgreSQL 的
GENERATED ALWAYS AS (NULLIF(col, '')) STORED)可强制转换,但增加维护成本
GROUP BY 和聚合函数里 '' 与 NULL 会分组吗?
会——它们被当作不同值处理:
-
GROUP BY col中,所有NULL被归为一组,所有''被归为另一组 -
COUNT(col)忽略NULL,但计入'';COUNT(*)计入全部行 - 若想合并统计,得先归一:
GROUP BY COALESCE(col, '')或GROUP BY NULLIF(col, '')
空字符串和 NULL 的语义差异在 JOIN 条件、ORDER BY(NULLS FIRST/LAST)、唯一约束(多数 DB 允许多个 NULL 但不允许重复 '')里都会暴露,必须从建表阶段就明确字段是否允许空串、是否允许 NULL、以及业务上“空”的定义到底是什么。










