在数据库查询里,把姓和名拼成全名、把地址各段合并成完整街道,都离不开字符串连接操作。不同数据库提供的连接函数和运算符并不统一,理解它们的语法与特性,是写出可维护SQL的基础。

一、主流数据库的连接方式
SQL标准里定义了双竖线||作为字符串连接运算符,但各家支持程度不同。MySQL默认不开启||的字符串语义,而是当成逻辑或;PostgreSQL和Oracle则原生支持||。为了兼容性与明确意图,多数项目会优先使用函数形式。
下面列出三种常见库的基础写法。MySQL与SQL Server均提供concat函数,但SQL Server也允许用加号+连接,而加号在数值上下文会产生隐式转换,容易引发意外。Oracle的concat只接受两个参数,多段拼接必须嵌套。
-- MySQL / SQL Server SELECT concat(first_name, ' ', last_name) AS full_name FROM users; -- PostgreSQL 也支持双竖线 SELECT first_name || ' ' || last_name AS full_name FROM users; -- Oracle 嵌套concat SELECT concat(concat(first_name, ' '), last_name) FROM users;
二、NULL值的处理差异
连接操作中NULL的处理是最容易出错的地方。在MySQL里,concat只要有一个参数为NULL,结果就整体为NULL。这对拼接可选字段非常不友好,比如中间名可能为空,直接concat会导致全名也空掉。
MySQL提供了concat_ws(with separator),第一个参数是分隔符,后续参数中的NULL会被忽略而不是拖垮整个结果。SQL Server的+运算符在NULL参与时同样返回NULL,需要用isnull或coalesce提前转换。PostgreSQL的||也会因NULL变NULL,但可用coalesce包裹。
-- MySQL concat_ws 忽略NULL
SELECT concat_ws(' ', first_name, middle_name, last_name) FROM users;
-- SQL Server 处理NULL
SELECT first_name + ' ' + ISNULL(middle_name, '') + ' ' + last_name FROM users;
-- PostgreSQL 使用coalesce
SELECT coalesce(first_name, '') || ' ' || coalesce(last_name, '') FROM users;
各库NULL行为对比
| 数据库 | 函数/运算符 | 遇NULL结果 |
|---|---|---|
| MySQL | concat | 整体NULL |
| MySQL | concat_ws | 跳过NULL |
| SQL Server | + | 整体NULL |
| PostgreSQL | || | 整体NULL |
| Oracle | || | 整体NULL |
三、性能与字符集注意点
从执行原理看,字符串连接会在内存中分配新缓冲区,把各段按字符集编码拷贝进去。如果字段很长或行数极多,连接操作会带来明显的临时空间开销。在MySQL的InnoDB中,含连接列的排序还可能触发磁盘临时表。
另一个隐形坑是字符集不一致。比如一个列是utf8mb4,另一个是latin1,连接时数据库会做隐式转换,可能丢失特殊字符或拖慢查询。建表时统一字符集、或在连接前用convert显式转换,能规避这类问题。
-- 显式统一字符集再连接 SELECT concat(cast(col_a AS CHAR CHARACTER SET utf8mb4), col_b) FROM mixed_charset_table;
四、跨库兼容的写法建议
如果系统需要同时跑在多种数据库上,推荐使用concat加coalesce的组合,因为concat在MySQL、SQL Server、PostgreSQL中都是函数(虽Oracle限两参数),而coalesce是标准SQL函数,可移植性高。
对于超过两段的拼接,可以封装成视图或在应用层处理。当必须在Oracle拼三段以上时,用嵌套concat配合coalesce即可,虽然可读性稍差,但能保证逻辑一致。
-- 较通用的三段拼接(Oracle需嵌套) SELECT concat(coalesce(a, ''), concat(coalesce(b, ''), coalesce(c, ''))) FROM t;
掌握这些函数差异与避坑点,日常写查询时就能少踩空值丢失、迁移报错的坑,也让SQL在团队不同技术栈之间更平稳地流转。