在关系型数据库里,数据经常会被拆成多个列来存储,比如用户的姓和名、地区的省和市。查询时如果希望把这些分散的字段合并成一段可读的文本,就需要用到字符串拼接能力。CONCAT函数正是SQL标准中用于完成多字段拼接的基础函数,它接收两个或多个参数,按从左到右的顺序把它们连接成单个字符串返回。

一、CONCAT函数的基本语法与作用
CONCAT函数的核心作用,是把传入的多个字符串表达式拼接为一个字符串。它的基本调用形式在不同数据库中基本一致,都是CONCAT(str1, str2, ...)。这里的每个参数可以是表里的字段名、字符串常量,也可以是其他函数执行后的返回值。
以MySQL为例,下面的语句把 first_name 和 last_name 两列拼成全名:
SELECT CONCAT(first_name, last_name) AS full_name FROM users;
如果希望姓名之间有个空格,就要显式把空格当常量传进去:
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM users;
这种写法比用加号或双竖线拼接更直观,也更容易避免类型转换上的隐式错误。CONCAT会按数据库规则把非字符串类型的参数转成字符串,再执行连接。
二、不同数据库中NULL值的处理差异
使用CONCAT时最容易踩的坑,就是NULL对结果的影响。在MySQL中,只要CONCAT的任意一个参数为NULL,整个返回结果就是NULL。这和很多开发者的直觉不同,常导致拼接后整列变空。
-- MySQL中,若last_name为NULL,结果就是NULL SELECT CONCAT(first_name, ' ', last_name) FROM users;
为了解决这个问题,可以用IFNULL或COALESCE把NULL转成空串:
SELECT CONCAT(first_name, ' ', COALESCE(last_name, '')) FROM users;
而在SQL Server里,CONCAT函数被设计为自动把NULL当作空字符串处理,因此不需要额外包一层函数。这种差异要求我们在跨数据库写SQL时,必须确认目标库对NULL的拼接规则,否则迁移代码后逻辑会悄悄变化。
三、CONCAT_WS与多字段带分隔符拼接
当要拼接的字段很多,并且都希望用同一个分隔符(比如逗号、斜杠)隔开时,反复写分隔符既麻烦又容易漏。此时可以用CONCAT_WS函数,WS是With Separator的缩写,第一个参数是分隔符,后面才是要拼接的内容。
-- 用斜杠拼接省、市、区,NULL会被忽略而不会留下多余斜杠
SELECT CONCAT_WS('/', province, city, district) AS region
FROM addresses;
CONCAT_WS只会把分隔符插在非NULL的参数之间。如果某个字段是NULL,它既不会参与拼接,也不会产生多余的分隔符。相比手工用CONCAT加分隔符,CONCAT_WS在字段可选的场景下明显更干净,也减少了因NULL造成的分隔符错位问题。
四、CONCAT结合函数与表达式的进阶用法
CONCAT的参数不限于原始列,也可以嵌套其他函数,比如日期格式化、数值处理等。这样能在一行SQL里完成较复杂的展示逻辑,避免把数据拉到应用层再拼。
SELECT
CONCAT(
'用户:',
username,
' 注册于:',
DATE_FORMAT(created_at, '%Y-%m-%d')
) AS info
FROM users;
上面例子里,把常量、列、DATE_FORMAT的结果混在一起拼成一句话。这种写法在生成导出报表的描述列时非常实用。不过要注意,嵌套过多会让SQL变长变难维护,简单展示可以接受,复杂文本建议在应用代码里组装。
五、常见误区与性能注意点
一个常见误区是认为CONCAT能自动处理所有类型的转换并显示友好格式。实际上,像DECIMAL、DATETIME这类类型,直接拼进CONCAT依赖数据库默认转换,可能得到意料外的格式或精度截断。先显式转换再拼更稳妥。
SELECT CONCAT('金额:', CAST(amount AS CHAR(20))) FROM orders;
性能上,CONCAT本身只是内存里的字符串操作,开销很小。但如果对拼接结果再做LIKE过滤或排序,可能导致无法使用索引,进而全表扫描。此时应考虑是否在表里冗余拼接列,或用生成列来兼顾查询效率。
| 数据库 | CONCAT遇NULL | 推荐写法 |
|---|---|---|
| MySQL | 整体返回NULL | 用COALESCE包字段 |
| SQL Server | NULL当空串 | 直接CONCAT |
| PostgreSQL | 整体返回NULL | 用COALESCE或||操作符 |
六、总结
CONCAT是SQL里做多字段拼接最直接的函数,理解它在不同库里对NULL的处理,是写出稳定查询的前提。字段多且有统一分隔符时,优先用CONCAT_WS减少出错。把CONCAT和类型转换、日期函数结合,可以一站式生成报表文本,但也要留意拼接后过滤带来的索引失效风险。