min/max忽略null但保留空字符串'',因''是合法非空值且字典序最小,可能被误判为极值;需用trim和nullif显式排除以保障业务准确性。

WHERE column = '' 不会匹配 NULL,但 MIN/MAX 会忽略 NULL 而保留 ''
空字符串 '' 和 NULL 在 SQL 中语义完全不同:NULL 表示“未知”,而 '' 是一个合法、非空、长度为 0 的字符串值。因此 MIN() 和 MAX() 会把 '' 当作有效值参与比较,但直接跳过所有 NULL。结果就是:哪怕表里有大量 NULL,只要存在一个 '',它就可能成为 MIN() 的返回值(因为多数校对规则下 '' 排在最前)。
空字符串在字典序中通常比所有非空字符串都“小”
MySQL 对字符串执行 MIN() 时,按当前字段的 COLLATION 做逐字符比较。'' 没有任何字符,所以它天然排在任何非空字符串之前——无论内容是 '0'、'a' 还是 '张'。这意味着:
-
MIN(name)可能返回'',即使你期望的是字典序最小的“真实姓名” - 如果业务上把
''当作“未填写”,那这个最小值就完全失真 - 用
ORDER BY name LIMIT 1查到的首行,也会是空字符串,和MIN()行为一致
如何安全地排除空字符串再求极值
不能依赖 WHERE name != '' 简单过滤,因为还要同时处理 NULL 和空白符(如空格、制表符)。推荐组合判断:
- 用
TRIM(name) = ''判定“逻辑上为空”,比name = ''更鲁棒 - 显式排除:
SELECT MIN(name) FROM t WHERE TRIM(name) != '' AND name IS NOT NULL - 更简洁写法(MySQL):
SELECT MIN(NULLIF(TRIM(name), '')) FROM t—— 先去空格,再把空字符串转成NULL,让MIN()自动跳过 - 注意:如果整列只剩
''和NULL,结果仍是NULL,需用COALESCE(MIN(...), 'N/A')做兜底
真正容易被忽略的是:空字符串会影响索引有效性
当字段允许 '' 且高频出现时,MIN()/MAX() 虽然能走索引,但优化器可能因数据分布倾斜(比如 90% 是 '')放弃使用索引最左前缀,退化为扫描。更隐蔽的问题是:如果你在 WHERE 中写 name > '' 想跳过空值,某些校对规则(如 utf8mb4_bin)下它确实生效;但在 _ci 规则下,大小写不敏感可能导致行为不一致。验证方式始终是:EXPLAIN SELECT MIN(name) FROM t WHERE TRIM(name) != '' 看是否用了索引。











