CONCAT函数干起活来很直接:把所有非NULL的参数按顺序拼成一串,但只要有任何一个参数是NULL,整条结果就跟着变NULL。参数数量不限,数字什么的它会自动转成字符串。不过实际业务里,NULL值防不胜防,最好配合CONCAT_WS或者IFNULL/COALESCE来兜底,否则很容易翻车。

CONCAT函数的基本用法和参数要求
MySQL 5.0.22+ 和 MariaDB 都原生支持 CONCAT(),它的规则很简单:把所有非NULL参数按顺序拼起来,一旦遇到NULL,直接返回NULL。这个特性特别容易踩坑——哪怕只有一个字段是NULL,整条结果就空了,不是想象中的留空或者变成空格。
CONCAT('a', 'b', 'c')→'abc',标准操作CONCAT(first_name, ' ', last_name)→ 如果first_name为NULL,结果就是NULL,不会变成' NULL',更不会帮你把两个名字中间空出来- 参数可以传任意多个,但每个都必须是字符串类型,或者能隐式转成字符串的值——比如数字会自动转成字符形式
处理NULL值:用CONCAT_WS或IFNULL兜底
实际查表的时候,姓名、地址这类字段里藏着大量NULL,直接用CONCAT会导致一堆空结果,根本没法用。一般两种解法比较靠谱:
- 用
CONCAT_WS(' ', first_name, middle_name, last_name):第一个参数指定分隔符,它自动跳过NULL值,只拼接非空部分,干净利落 - 显式补空:
CONCAT(IFNULL(first_name, ''), ' ', IFNULL(last_name, '')),控制粒度更细,但代码会稍长 - 注意:
CONCAT_WS的分隔符只出现在非NULL值之间,不会在开头或结尾多出来,这个细节很贴心
不同数据库的兼容性差异
CONCAT()在 MySQL 和 MariaDB 里行为一致,但换到其他数据库,函数名可能根本不认:
- PostgreSQL 习惯用
||操作符:first_name || ' ' || last_name - SQL Server 用
+:first_name + ' ' + last_name,但它的NULL + anything同样返回NULL,也得靠ISNULL()处理 - SQLite 也支持
CONCAT(),但本质上它是||的别名,底层还是连接符的那套逻辑 - 如果写跨库SQL,优先考虑标准的
||写法(先确认目标库是否支持),或者统一用COALESCE组合来更安全地处理 NULL
性能和可读性提醒
拼接本身的开销很小,但有两个地方值得特别留心:
- 在
WHERE条件里用CONCAT去查字段,比如WHERE CONCAT(first_name, last_name) = 'JohnDoe',这会导致索引失效,全表扫描的风险很高 - 复杂拼接最好放到应用层去做,特别是带有条件逻辑的场景(比如“有middle_name才加空格”),SQL里嵌套太多
IF()或CASE不仅难写,后期维护也头疼 - 别为了省一行代码把多个
CONCAT嵌套起来写,比如CONCAT(CONCAT(a,b), CONCAT(c,d)),直接平铺更清晰,可读性也好得多
真正麻烦的是字段类型混合(比如 INT 和 VARCHAR 混拼)再加上 NULL 判断,还要兼顾跨库适配——这时候不如先想清楚业务到底需要拼什么、在哪个环节用、谁来消费这个结果,别一上来就堆 SQL。
