concat遇null必返null是mysql严格遵循sql标准的设计行为,非bug;concat_ws自动跳过null字段但要求分隔符非null,coalesce/ifnull可用于预处理替换null值。

CONCAT遇到NULL就返回NULL是MySQL的硬规则
不是bug,是设计行为:只要CONCAT()任意一个参数为NULL,整条结果必定是NULL。比如CONCAT('a', NULL, 'c')返回NULL,不是'ac'。这在用户表里middle_name为空、日志字段缺失等场景下,会直接让整行拼接字段变空——应用层可能报空指针,报表里突然大片空白。
优先用CONCAT_WS跳过NULL字段
CONCAT_WS(With Separator)是更省心的选择,它自动忽略NULL值,只拼接非空部分,且语义明确。
- 分隔符不能为
NULL,否则整列变NULL;但字段值为NULL完全无影响 - 写法:
CONCAT_WS(' ', first_name, middle_name, last_name)→middle_name为NULL时输出'Zhang Li',不是'Zhang Li' - 分隔符支持多字符:
CONCAT_WS(' → ', dept, team)比嵌套CONCAT清晰得多 - 注意:
CONCAT_WS(NULL, a, b)会崩,务必检查第一个参数是否真为非空值
必须兜底时用COALESCE或IFNULL预处理
当需要严格控制空值替换逻辑(比如把NULL转成'N/A'而非空字符串),或使用CONCAT本身(如兼容老视图、跨库迁移需保留原函数名),就得手动兜底。
-
COALESCE(col, '')是标准写法,支持多参数,MySQL/PostgreSQL/SQL Server通用 -
IFNULL(col, '')仅MySQL可用,性能略优但不跨库 - 错误示范:
CONCAT(first_name, ' ', middle_name, ' ', last_name)→ 任一字段NULL全崩 - 正确写法:
CONCAT(COALESCE(first_name, ''), ' ', COALESCE(middle_name, ''), ' ', COALESCE(last_name, ''))
别在WHERE或ON里用CONCAT做条件匹配
CONCAT不走索引,一旦写进WHERE或JOIN条件,基本等于放弃优化。
- 例如:
WHERE CONCAT(name, id) = 'Alice1001'→ 全表扫描 - 想按拼接后值查,应提前建生成列并加索引(MySQL 5.7+):
ALTER TABLE users ADD full_id VARCHAR(50) GENERATED ALWAYS AS (CONCAT(name, id)) STORED, ADD INDEX idx_full_id (full_id) -
CONCAT_WS同样不走索引,聚合场景该用GROUP_CONCAT,标量拼接别指望它加速查询
CONCAT_WS虽跳过NULL,但分隔符一旦是NULL,结果照样全空——这个细节在动态拼接分隔符时特别危险。











