首页/数据/SQL 速查/CONCAT 字符串拼接
函数速查60 条

CONCAT 字符串拼接

拼接多个字符串:MySQL 的 CONCAT 遇到 NULL 会让整行结果变 NULL,带分隔符拼接用 CONCAT_WS 会跳过 NULL 项。

SQL 速查数据更新于 2026-10-13

CONCAT 是什么

CONCAT 把多个字符串拼成一个字符串,是最常用的字符串函数之一。MySQL 的 CONCAT 只要有一个参数为 NULL,整个结果就是 NULL,这与很多人的直觉相反;需要忽略 NULL 时用 CONCAT_WS,它用第一个参数作分隔符并跳过后续的 NULL 参数。PostgreSQL 的 concat() 会忽略 NULL 参数,而 || 运算符遇到 NULL 返回 NULL,函数与运算符的行为不一致,迁移 SQL 时要逐个核对。

基本信息

MySQL 基本拼接CONCAT(a, b, c),任一参数为 NULL 则结果为 NULL
MySQL 带分隔符CONCAT_WS(sep, a, b, c),跳过 NULL 参数;sep 为 NULL 时结果为 NULL
PostgreSQL 函数concat(a, b) 忽略 NULL 参数
PostgreSQL 运算符a || b 遇到 NULL 返回 NULL
MySQL 的 ||默认是逻辑或,只有开启 PIPES_AS_CONCAT 才是拼接
非字符串参数数字与日期会自动转换为字符串再拼接

典型使用场景

  • 拼完整地址:省加市加区加详细地址,缺失部分用 COALESCE 兜底
  • 生成展示名:姓加名、商品标题加规格
  • 拼业务编号:给流水号加固定前缀,如 ORDER-20240501-0001
  • 拼日志或对账文本:把多字段拼成一行便于比对
  • 补全固定格式:给手机号或证件号加掩码片段
  • 拼动态 SQL 片段:生成表名或测试数据(注意不要拼用户输入)

示例

示例
-- MySQL
SELECT CONCAT(province, city, district) AS addr FROM users;
SELECT CONCAT_WS('-', 'ORDER', '20240501', '0001') AS order_no;  # ORDER-20240501-0001

-- 任一参数为 NULL,CONCAT 整体为 NULL
SELECT CONCAT('name: ', nickname) FROM users;                  # nickname 为 NULL 时整列为 NULL
SELECT CONCAT('name: ', COALESCE(nickname, '')) FROM users;    # 兜底后不再变 NULL

-- PostgreSQL
SELECT concat('name: ', nickname);                    # 忽略 NULL
SELECT 'name: ' || COALESCE(nickname, '');            # 用 || 要自己兜底

NULL 行为对照

写法MySQLPostgreSQL
CONCAT(a, NULL)返回 NULLconcat 忽略 NULL 返回 a
CONCAT_WS('-', a, NULL)跳过 NULL 参数concat_ws 行为一致
a || b 遇 NULL默认按逻辑或处理返回 NULL
concat_ws(NULL, a, b)返回 NULL返回 NULL
拼出来的是新值,不修改原列:想落库要配合 UPDATE … SET col = CONCAT(…),并先确认目标列长度够。
目标列是定长 CHAR 时,拼接结果可能被截断或补空格;长度不确定时用 VARCHAR 或 TEXT,并让数据库不启严格模式外的静默截断。
不要把用户输入直接拼进 SQL 文本再执行,这是注入的入口;需要动态标识符时必须用白名单或引号函数处理。
MySQL 里 GROUP_CONCAT 是分组内拼接,PostgreSQL 里对应 string_agg(col, sep),二者都受最大长度参数限制。

拼接实践要点

  • 拼接前统一兜底:对可能为 NULL 的列先用 COALESCE 换成空串
  • 留意结果长度:拼接后长度是各段之和,超出目标列长度会被截断
  • 分隔符统一用 CONCAT_WS:它跳过 NULL,不会出现连续两个分隔符
  • 分组内拼接要指定顺序:GROUP_CONCAT 内部补 ORDER BY,否则拼接顺序不确定
  • 展示类拼接可放到应用层:跨库可移植性与格式灵活性更好,SQL 里只取原始字段
  • 拼接串进日志前先脱敏:日志里的拼接结果常是敏感信息的泄露点
MySQL 的 GROUP_CONCAT 受 group_concat_max_len 控制,默认 1024 字节,拼接长文本前要先调大,否则结果被静默截断。
数字与日期参与拼接时按会话格式转换,不同环境结果可能不同;格式要求严格时先用 DATE_FORMAT 或 to_char 转成字符串再拼。

拼接与迁移要点

  • 迁移 SQL 时逐条核对 NULL 行为:MySQL 的 CONCAT 与 PostgreSQL 的 concat 并不等价
  • 拼接结果要写回表时先估算长度:超长在严格模式报错、非严格模式静默截断
  • 拼接进 SQL 语句要转义:宁可用参数占位符,也不要手工拼字符串
  • 大批量拼接注意内存:应用层拼接更灵活,也更容易分批处理
  • 格式模板固定时交给应用层模板引擎:SQL 只取原始字段,展示格式变更不必改 SQL
MySQL 里最外层再套一次 COALESCE 是常见兜底:COALESCE(CONCAT(province, city), '') 可以保证前端拿到的是空串而不是空值。
拼接不同字符集的列时数据库可能要做隐式转换,既慢又可能出现乱码;跨库或跨字符集拼接前先确认两侧列的字符集一致。

易错点

  • MySQL 的 CONCAT 遇到 NULL 会让整列变成 NULL,拼接前用 COALESCE 兜底
  • 把 MySQL 的 || 当成拼接符,实际是逻辑或,得到 0 或 1 而不是字符串
  • 用 CONCAT 拼 SQL 语句并混入用户输入,导致注入风险
  • 拼接结果超出目标列长度被截断,严格模式下直接报错、非严格模式下静默丢数据
  • CONCAT_WS 的第一个参数为 NULL 时整体为 NULL,把可变的分隔符放在第一个位置要小心

数据来源与参考

  • MySQL 8.0 Reference Manual · String Functions
  • PostgreSQL Documentation · String Functions and Operators
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌