在关系型数据库的日常查询里,把多个字段或者常量组合成一段完整文本是高频需求。CONCAT函数作为标准SQL提供的字符串拼接工具,能够将传入的多个参数按顺序连接成单个字符串,广泛用于生成全名、完整地址、日志描述等场景。
一、CONCAT函数的基础用法
CONCAT函数的基本语法非常简单,它接受两个或多个字符串类型的参数,并将它们依次拼接。以MySQL为例,下面的语句把 first_name 和 last_name 两个字段合并为全名:
SELECT CONCAT(first_name, last_name) AS full_name FROM user;
如果希望在姓和名之间保留一个空格,只需要把空格作为字符串常量传入即可:
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM user;
需要注意的是,不同数据库对NULL参数的处理并不一致。在MySQL中,只要有一个参数为NULL,CONCAT的返回结果就是NULL;而在Oracle里,NULL会被当作空字符串处理,不影响最终拼接结果。因此在跨库开发时,往往要结合IFNULL或NVL函数来兜底。
二、CONCAT_WS:带分隔符的拼接
当我们需要用统一的分隔符连接多个字段时,反复写分隔符既繁琐又容易出错。CONCAT_WS(With Separator)第一个参数是分隔符,后续参数才是待拼接的内容:
SELECT CONCAT_WS('-', province, city, district) AS region
FROM address;
CONCAT_WS会自动忽略NULL值,不会在结果中留下多余的分隔符。例如当 district 为NULL时,结果只会是 province-city,而不会变成 province-city- 这种尾部多横杠的形式。
相比普通CONCAT,CONCAT_WS在拼接地址、路径、标签列表时更加健壮。它减少了人工判断空值逻辑的代码量,也让SQL语义更清晰,是处理可选字段组合的首选方案。
三、其他拼接方式与数据库差异
除了CONCAT系列函数,不同数据库还提供了运算符式的拼接写法。MySQL和SQL Server支持使用加号(+)或双竖线(||)进行拼接,但双竖线在Oracle和PostgreSQL中才是标准连接符,在MySQL里默认表示逻辑或,需要开启PIPES_AS_CONCAT模式才能用于字符串连接。
-- PostgreSQL/Oracle 写法 SELECT first_name || ' ' || last_name FROM user; -- SQL Server 写法 SELECT first_name + ' ' + last_name FROM user;
下表汇总了主流数据库在字符串拼接上的特性差异:
| 数据库 | 主要拼接方式 | NULL处理 |
|---|---|---|
| MySQL | CONCAT、加号 | CONCAT遇NULL返回NULL |
| Oracle | CONCAT、双竖线 | NULL视为空串 |
| SQL Server | 加号、CONCAT | 加号遇NULL返回NULL |
| PostgreSQL | 双竖线、CONCAT | 双竖线遇NULL返回NULL |
从可移植性角度看,尽量使用标准CONCAT并在应用层或SQL中显式处理NULL,能降低迁移数据库时的改造成本。
四、常见业务拼接场景
1. 生成用户展示名
很多系统需要把昵称和账号组合展示,比如“张三(zhangsan)”。用CONCAT可以一行搞定:
SELECT CONCAT(nickname, '(', account, ')') AS show_name
FROM user_profile;
这种写法比后台代码拼接更早完成数据加工,能减少传输字段数量。当 nickname 可能为空时,可改用CONCAT_WS或包裹IFNULL来保证括号里至少有账号信息。
2. 拼接完整收货地址
订单详情页常要把省、市、区、街道合并。使用CONCAT_WS既干净又能跳过空字段:
SELECT order_id,
CONCAT_WS('', province, city, district, street, detail)
AS full_address
FROM orders;
这里分隔符传空串,等价于直接连写。若某些老地址数据缺省份,也不会出现奇怪的间隔符,保证前端展示连贯。
3. 分组内多值串接
在统计每个部门员工姓名时,可配合GROUP_CONCAT(MySQL)或STRING_AGG(PostgreSQL、SQL Server)实现组内拼接:
SELECT dept_id,
GROUP_CONCAT(emp_name SEPARATOR ',') AS emp_list
FROM employee
GROUP BY dept_id;
这类聚合拼接本质是CONCAT思想在分组上的延伸,能把一对多关系压缩成单行文本,便于导出或快速浏览,但要注意超长截断问题,必要时调整 group_concat_max_len 参数。
五、性能与避坑建议
在大数据集上做字符串拼接本身不会太耗资源,但如果拼接列上没有函数索引,且拼接后用于WHERE过滤,就会导致全表扫描。建议把拼接结果放在SELECT中用于展示,过滤条件仍使用原字段。
避免在CONCAT内部嵌套复杂子查询,这会让每行都重复执行子查询逻辑,拖慢整体响应。
另外,字符集不一致的列拼接可能产生乱码或隐式转换错误。确保相关字段使用统一字符集(如utf8mb4),并在跨库同步时校验元数据定义,才能稳定输出正确文本。