mysql中concat遇null即返null,应改用concat_ws或ifnull处理;拼接数值需先转字符串;where中禁用concat以免索引失效;注意字符集统一防乱码。

CONCAT 函数拼接字段时 NULL 会让整条结果变 NULL
MySQL 的 CONCAT 对 NULL 零容忍:只要任意一个参数是 NULL,整个返回值就是 NULL。这不是 bug,是设计行为,但常让人误以为字段没数据或拼接失效。
- 用
CONCAT_WS替代(带分隔符且自动跳过NULL):CONCAT_WS(', ', first_name, middle_name, last_name) - 手动转
NULL为字符串:CONCAT(IFNULL(first_name, ''), ' ', IFNULL(last_name, '')) - 注意
CONCAT('a', NULL)返回NULL,不是'a'—— 别靠测试一两个非空值就下结论
多字段拼接要加空格或分隔符?别硬写字符串常量
直接写 CONCAT(name, ' ', age) 看似简单,但一旦某字段是 NULL 或数值类型(如 age 是 INT),可能触发隐式转换异常或意外空格。更稳的方式是明确类型和边界。
-
age是数字?先用CAST(age AS CHAR)或CONVERT(age, CHAR)转成字符串再拼 - 想加固定分隔符(比如逗号+空格),优先用
CONCAT_WS(', ', col1, col2, col3)—— 它天然忽略NULL,且不额外在开头/结尾补分隔符 - 避免
CONCAT(col1, ' ', col2, ' ', col3)这种写法:如果col2为空字符串或NULL,你会得到多余空格,后续TRIM()治标不治本
CONCAT 性能没问题,但别在 WHERE 里对字段做 CONCAT 查询
CONCAT 本身开销极小,但在 WHERE 子句中用于拼接列来匹配(比如 WHERE CONCAT(first, last) = 'JohnDoe')会彻底失效索引,查得慢还难优化。
- 这种查询无法走
first或last上的索引,等价于全表扫描 - 真要按拼接结果查,建生成列 + 索引更靠谱:
ALTER TABLE users ADD full_name VARCHAR(100) GENERATED ALWAYS AS (CONCAT(first_name, last_name)) STORED,再给full_name加索引 - 临时拼接展示用
SELECT CONCAT(...)完全 OK;拿它当查询条件,就是给自己埋坑
不同 MySQL 版本对 CONCAT 参数个数没限制,但要注意字符集混合
8.0 和 5.7 都支持任意多个参数传给 CONCAT,但如果你拼接的字段来自不同字符集(比如 utf8mb4 和 latin1),MySQL 会尝试隐式转换,可能报错或乱码。
- 查字段字符集:
SHOW FULL COLUMNS FROM table_name LIKE 'col_name',看Collation列 - 强制统一用
CONVERT(col USING utf8mb4)再拼:CONCAT(CONVERT(name USING utf8mb4), ' - ', CONVERT(descr USING utf8mb4)) - 建表时就统一字符集比后期补救省心得多,尤其涉及中文、emoji 时
最常被忽略的是字符集隐式转换——看起来拼出来了,导出 CSV 却发现某些字段乱码,回头查才发现两个源字段一个是 utf8mb4_general_ci,一个是 latin1_swedish_ci。










