MySQL的CONCAT函数遇NULL即返回NULL,需用IFNULL/COALESCE兜底;CONCAT_WS自动跳过NULL且首参为分隔符;字符集不一致易致乱码,应统一为utf8mb4;WHERE中使用CONCAT会导致索引失效。

CONCAT函数的基本用法和空值陷阱
MySQL的CONCAT函数不会自动跳过NULL,只要任意一个参数是NULL,整个结果就是NULL。这不是bug,是设计行为——很多初学者拼接失败就卡在这儿。
- 正确写法:
CONCAT('a', 'b', 'c')→'abc' - 常见翻车:
CONCAT('name: ', name, ', age: ', age),如果name或age为NULL,整条记录返回NULL - 安全做法:用
IFNULL或COALESCE兜底,比如CONCAT('name: ', IFNULL(name, ''), ', age: ', IFNULL(age, ''))
CONCAT_WS比CONCAT更适合带分隔符的拼接
当你要用逗号、竖线或斜杠分隔多个字段时,别硬套CONCAT,改用CONCAT_WS(WS = With Separator)——它自动跳过NULL参数,且第一个参数固定为分隔符。
-
CONCAT_WS(', ', 'apple', NULL, 'cherry')→'apple, cherry'(NULL被忽略) -
CONCAT_WS(' | ', first_name, middle_name, last_name)更简洁,也更健壮 - 注意:
CONCAT_WS第一个参数必须是非NULL字符串,否则整个结果是NULL;分隔符本身不能是NULL
字符集不一致导致乱码或隐式转换失败
如果拼接的字段来自不同表或不同列定义(比如utf8mb4和latin1),CONCAT可能报错或输出乱码,尤其在开启严格模式时。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 检查方式:
SHOW VARIABLES LIKE 'character_set%';+SHOW FULL COLUMNS FROM table_name; - 临时解决:用
CONVERT或CAST统一编码,例如CONCAT(CONVERT(col1 USING utf8mb4), col2) - 长期建议:建表时统一用
utf8mb4,并设置默认校对规则如utf8mb4_0900_as_cs
性能影响:别在WHERE或ORDER BY里用CONCAT做计算
在WHERE条件中写WHERE CONCAT(first_name, ' ', last_name) = 'John Doe'会导致全表扫描,索引失效。
- 原因:
CONCAT是运行时计算,无法利用first_name或last_name的索引 - 替代方案:用复合索引+多条件,比如
WHERE first_name = 'John' AND last_name = 'Doe' - 如果真要模糊查全名,考虑生成列(Generated Column)加索引:
ALTER TABLE users ADD full_name VARCHAR(255) GENERATED ALWAYS AS (CONCAT(first_name, ' ', last_name)) STORED;
真正麻烦的不是语法记不住,而是NULL处理、字符集混用和索引失效这三点——它们往往藏在看似正常的SQL背后,等数据量上来才暴露。

















