必须分开处理 null 和空字符串:判断 null 用 is null,空字符串用 = '';混用会导致漏数据或误判;业务上“不能为空”需同时检查 is not null 和 trim(col) != ''。

必须分开处理,不能混用 IS NULL 和 = '',否则会漏数据或误判。
判断 NULL 必须用 IS NULL,别碰 = NULL
MySQL 中 NULL 是“未知”,不是值,= NULL 永远返回 UNKNOWN,WHERE 条件不成立,查不到任何记录。常见错误是写成 WHERE name = NULL 或 WHERE name != '' 试图一并排除两者——这既抓不到 NULL,也漏掉空串。
- 正确查
NULL:WHERE name IS NULL - 正确查非
NULL:WHERE name IS NOT NULL - 别写
WHERE name = NULL,它等价于没写条件 - 触发器或存储过程中也一样:
IF name IS NULL THEN ...才生效
同时过滤 NULL 和空字符串要显式组合
业务上常说的“字段不能为空”,往往指既不能是 NULL,也不能是 ''(甚至还要剔除纯空白如 ' ')。单靠一个条件做不到,必须叠加判断。
- 基础写法:
WHERE name IS NOT NULL AND name != '' - 更健壮(去空格):
WHERE name IS NOT NULL AND TRIM(name) != '' - 在 UPDATE 或 INSERT 触发器里,如果要阻止插入,得在
BEFORE INSERT中用IF+SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'name cannot be empty'; - 别用
LENGTH(name) = 0替代name = '',因为LENGTH(NULL)返回NULL,整个表达式又掉进三值逻辑陷阱
字符串拼接和默认值替换要逐字段兜底
只要参与拼接的任意字段是 NULL,整个 CONCAT(a, b, c) 结果就是 NULL;IFNULL() 或 COALESCE() 必须作用在每个字段上,不能包在最外层。
- 错误写法:
IFNULL(CONCAT(first_name, ' ', last_name), 'Unknown')—— 拼接已崩,IFNULL无效 - 正确写法:
CONCAT(IFNULL(first_name, ''), ' ', IFNULL(last_name, '')) - 多级 fallback 推荐
COALESCE():COALESCE(phone, mobile, 'N/A'),但注意所有参数类型需一致(别混VARCHAR和INT) - 数值字段兜底别用字符串:
IFNULL(age, 'N/A')会报错,应写IFNULL(age, 0)
建表阶段就该定好语义,别全丢给查询补救
很多判断麻烦,根源在于建表时没区分“未提供”(NULL)和“明确为空”('')。后期硬加逻辑,容易漏、难维护。
- 推荐策略:业务上“可选填”字段设为
NULL并加注释;“必填但内容可为空”字段设NOT NULL DEFAULT '' -
COUNT(col)会跳过NULL但统计'',如果统计“有效填写数”,就得写COUNT(CASE WHEN col IS NOT NULL AND TRIM(col) != '' THEN 1 END) - LEFT JOIN 后在 WHERE 对右表字段写
IS NULL,实际会把INNER JOIN效果,要小心——这是最容易被忽略的隐性陷阱











