concat函数遇null即返null,需用ifnull/coalesce兜底;concat_ws自动跳过null且适配分隔符;字符集不一致易致乱码或报错,应统一为utf8mb4;大量拼接影响性能,建议移至应用层或用生成列加索引。

CONCAT函数遇到NULL会整个返回NULL
这是最常踩的坑:只要任意一个参数是NULL,CONCAT()就直接返回NULL,而不是跳过或转为空字符串。比如CONCAT('a', NULL, 'b')结果是NULL,不是'ab'。
实际场景中,字段可能为NULL(如用户没填“中间名”),直接拼接会导致整条记录显示为空。解决办法是用IFNULL()或COALESCE()提前兜底:
SELECT CONCAT( IFNULL(first_name, ''), ' ', IFNULL(middle_name, ''), ' ', IFNULL(last_name, '') ) AS full_name FROM users;
CONCAT_WS比CONCAT更适合带分隔符的拼接
当你要用固定分隔符(比如逗号、空格)连接多个字段时,CONCAT_WS()(WS = With Separator)更安全也更简洁。它自动跳过NULL参数,只对非NULL值生效,且第一个参数必须是分隔符。
对比一下:
-
CONCAT('a', NULL, 'c')→NULL -
CONCAT_WS(', ', 'a', NULL, 'c')→'a, c'
常见用法:
SELECT CONCAT_WS(' - ', product_name, model_year, color) AS display_name FROM products;
注意:CONCAT_WS()不会在开头或结尾多加分隔符,也不因连续NULL产生多余分隔符。
字符集不一致会导致CONCAT结果乱码或报错
如果参与拼接的字段/字面量字符集不同(比如utf8mb4和latin1混用),MySQL可能隐式转换失败,抛出Illegal mix of collations错误。
排查方法:用SHOW VARIABLES LIKE 'character_set%';确认服务端默认字符集,并检查字段定义:
SHOW CREATE TABLE users;
稳妥做法是显式转换:
SELECT CONCAT(
CONVERT(name USING utf8mb4),
' (',
CONVERT(id USING utf8mb4),
')'
) FROM users;
或者建表时统一用utf8mb4_unicode_ci,避免后期补救。
大量字符串拼接会影响查询性能
CONCAT()本身开销不大,但若在WHERE或ORDER BY里使用(比如WHERE CONCAT(first, last) LIKE '%john%'),会导致索引失效,全表扫描。
优化思路:
- 尽量把拼接逻辑移到应用层,尤其涉及复杂条件时
- 如必须在SQL中拼接并过滤,考虑用生成列(Generated Column)加索引:
ALTER TABLE users ADD COLUMN full_name VARCHAR(255)
GENERATED ALWAYS AS (CONCAT_WS(' ', first_name, last_name)) STORED;
然后对full_name建索引。注意STORED表示物理存储,VIRTUAL不存但每次计算——后者省空间,前者查得快。
真正麻烦的从来不是语法怎么写,而是你没意识到那个NULL字段正在悄悄让整列变空,或者没发现字符集正在后台打架。











