where column = '' 仅匹配空字符串,对 null 无效,因 null = '' 返回 unknown;需用 or 或 coalesce(column, '') = '' 同时覆盖两者。

WHERE column = '' 只匹配空字符串,不碰 NULL
直接写 WHERE column = '' 是筛选空字符串最干净的方式,但它对 NULL 完全无效——因为 NULL = '' 的结果是 UNKNOWN,不是 TRUE,所以该行不会进入结果集。这在 MySQL、PostgreSQL、SQL Server 都一致。
常见错误是:看到界面上某字段“空白”,就以为 = '' 能查全,结果漏掉大量 NULL 记录。尤其 ORM(如 Django 的 filter(name='') )默认只生成 = '',不会自动补 IS NULL。
- 适用场景:你明确只想找
INSERT INTO t (x) VALUES ('')这类人为插入的零长度字符串 - 风险点:字段允许
NULL且业务未强制 default,表里实际混着NULL和'',单用= ''会漏数据 - 验证方法:执行
SELECT column, LENGTH(column), ISNULL(column) FROM t WHERE column IN ('', NULL) OR column IS NULL LIMIT 5,看哪些是真''、哪些是NULL
同时筛空字符串和 NULL,用 OR 或 COALESCE
要真正“过滤掉所有无内容”的值,必须显式覆盖两种情况。最直白的是 WHERE column = '' OR column IS NULL;更紧凑的写法是 WHERE COALESCE(column, '') = ''(MySQL/PostgreSQL/SQL Server 都支持)。
COALESCE(column, '') 把 NULL 转成 '',再统一比 = '',语义清晰。但注意:如果字段含空格(如 ' '),它不会被识别为“空”,得先 TRIM()。
- 推荐组合:
WHERE COALESCE(TRIM(column), '') = ''—— 同时处理NULL、''、纯空格 - Oracle 特别注意:它把
''当作NULL处理,所以= ''永远不生效,只能用IS NULL;COALESCE(col, '')在 Oracle 里也等价于col,慎用 - 性能提示:
COALESCE(TRIM(col), '') = ''无法走普通索引,高频查询建议加函数索引或改用计算列
LIKE '%xxx%' 不能当空值过滤手段
WHERE column LIKE '%abc%' 看似能绕过空值问题,其实不行:NULL LIKE '...' 返回 UNKNOWN,'' LIKE '...' 返回 FALSE,两者都会被自然排除。但这属于副作用,不是设计意图。
问题在于语义断裂:你本意是“找含 abc 的记录”,顺带剔除了空值;但如果后续改成 LIKE '%'(匹配所有非 NULL 字符串),空字符串又会意外出现。靠 LIKE 过滤空值,等于把逻辑耦合进模糊匹配里,极易被破坏。
- 绝对不要写:
WHERE column LIKE '%' AND column IS NOT NULL—— 多余且误导 - 如果真要模糊查又想排除空值,分开写:
WHERE column IS NOT NULL AND column != '' AND column LIKE '%abc%' - 注意:SQL Server 中
LIKE对尾部空格敏感('a ' LIKE 'a'为FALSE),而 MySQL 默认忽略,行为不统一
INSERT/UPDATE 时 NULL 和 '' 的选择影响查询逻辑
空字符串 '' 和 NULL 在存储层就是两个不同值:前者是确定的零长度字符串,后者是缺失值。这个区别从写入那一刻就决定了后续所有查询怎么写。
比如应用层传参为 null,ORM 生成 INSERT ... VALUES (NULL);传空字符串 '',生成 VALUES ('')。一旦混用,查询条件就必须始终考虑双轨制。
- 统一策略建议:业务上“无值”就全用
NULL,避免'';或者全用''并禁止NULL(建表加NOT NULL DEFAULT '') - 迁移补救:已有混合数据,可用
UPDATE t SET col = NULL WHERE col = ''或反过来,但需评估外键、索引、应用兼容性 - 最容易被忽略的点:CHAR 类型字段在 MySQL 中会右填空格,
LENGTH(col)可能 >0 却显示为空;查之前务必TRIM(),否则= ''永远不命中










