CONCAT 函数的基本用法和空值陷阱
CONCAT是 MySQL 中最常用的字符串拼接函数,但它对
NULL值极其敏感:只要任意一个参数为
NULL,整个结果就变成
NULL。这不是 bug,是设计行为。 正确写法:
CONCAT('a', 'b', 'c') → 'abc'踩坑写法:
CONCAT('a', NULL, 'c') → NULL(不是
'ac') 安全替代:
CONCAT(COALESCE(col1, ''), COALESCE(col2, '')),或直接改用
CONCAT_WS
CONCAT_WS 更适合字段拼接场景
当你要用固定分隔符(比如逗号、竖线)连接多个字段时,
CONCAT_WS(W 代表 With Separator)更鲁棒,它自动跳过
NULL参数,且第一个参数必须是分隔符。
CONCAT_WS('-', 'John', NULL, 'Doe') → 'John-Doe'(
NULL被忽略)
CONCAT_WS('', a, b, c) 等价于 CONCAT(a, b, c),但依然跳过
NULL注意:
CONCAT_WS不接受表达式作为分隔符,比如
CONCAT_WS(IF(need_dash, '-', ''))会报错
与 + 运算符、|| 运算符的区别
MySQL 默认不启用
||作为字符串连接符(它被解析为逻辑 OR),除非开启
PIPES_AS_CONCATSQL 模式;而
+是数值加法,遇到字符串会强制转成数字,极易出错。
'1' + '2'→
3(不是
'12')
'a' + 'b'→
0(转换失败返回 0)
SET sql_mode = 'PIPES_AS_CONCAT'; SELECT 'a' || 'b';→
'ab',但该模式会影响其他逻辑,不推荐在生产环境全局开启
性能与索引友好性提醒
在
WHERE或
ORDER BY中对字段使用
CONCAT(如
WHERE CONCAT(first_name, last_name) = 'JohnDoe')会导致索引失效,因为无法走
first_name或
last_name的原有索引。 优化思路:提前计算并存入冗余字段(如
full_name),并为其建索引 或者改用前缀匹配:
WHERE first_name = 'John' AND last_name = 'Doe'
CONCAT本身开销极小,瓶颈永远在是否能命中索引,而不是函数调用
