首页/数据/SQL 速查/GROUP_CONCAT 分组拼接(MySQL)
聚合与窗口函数54 条

GROUP_CONCAT 分组拼接(MySQL)

把组内值拼成一个字符串:支持 DISTINCT、排序与自定义分隔符;默认长度上限 1024 字节,超出会静默截断。

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

GROUP_CONCAT 是什么

MySQL 的分组拼接函数:把同一组内的值拼成一个字符串,支持 DISTINCT、排序与自定义分隔符。最容易被忽略的一点是长度上限:group_concat_max_len 默认 1024 字节,超出部分会被静默截断,不报任何错误。

基本信息

语法GROUP_CONCAT([DISTINCT] expr [ORDER BY …] [SEPARATOR '…'])
默认分隔符英文逗号
长度上限group_concat_max_len 默认 1024 字节,可用 SET SESSION 调整
返回值字符串;组内没有值时返回 NULL
排序不写 ORDER BY 时拼接顺序不保证
PostgreSQL对应 string_agg(expr, ', ' ORDER BY …)

MySQL 分组拼接

MySQL 分组拼接
SELECT user_id,
       GROUP_CONCAT(DISTINCT product_name          -- 去重
                    ORDER BY product_name          -- 拼接前排序,保证结果可复现
                    SEPARATOR ', ') AS products    -- 自定义分隔符
FROM order_items
GROUP BY user_id;

-- 先确认当前上限,避免静默截断
SHOW VARIABLES LIKE 'group_concat_max_len';
SET SESSION group_concat_max_len = 8192;   -- 只影响当前会话

PostgreSQL 对应写法

PostgreSQL 对应写法
-- 用 string_agg 完成同样的拼接
SELECT user_id,
       string_agg(DISTINCT product_name, ', ' ORDER BY product_name) AS products
FROM order_items
GROUP BY user_id;
-- PG 没有隐式的长度截断,但结果过长仍会占用内存与网络带宽,导出前先估长度

参数与行为

参数作用注意
DISTINCT拼接前去重与 ORDER BY 配合时顺序按排序表达式
ORDER BY指定拼接顺序不写则顺序不保证
SEPARATOR自定义分隔符默认逗号,多字符也支持
长度上限group_concat_max_len超出静默截断,不报错
空组返回 NULL不是空字符串,展示时需兜底

典型使用场景

  • 把订单明细的商品名拼成一行,方便导出查看
  • 按用户聚合标签、权限编码列表
  • 生成调试用的条件字符串或核对清单
  • 拼接地址、联系人等分散字段
  • 把查询结果转成人类可读的一行文本
  • 把子表的值压缩到主表一行里展示,减少多次查询
上限是会话级的:SET SESSION 只影响当前连接,连接池换一条连接就失效。需要长期生效要改配置文件或全局设置,并在应用启动时统一设置。
截断是静默发生的:超过 group_concat_max_len 的部分直接丢失,下游解析会拿到不完整数据而日志里看不到任何错误。拼接长文本前先确认上限。

易错点

  • 不知道长度上限:结果被截断却没有任何报错,往往到下游解析出错才发现
  • 不写 ORDER BY:拼接顺序不保证,两次执行结果可能不同,做校验时会误报差异
  • 把拼接结果当查询条件:逗号串做 IN 或关联无法使用索引,规范做法是保留关系表
  • 一次性拼接超大结果集:内存占用激增,还可能超过客户端报文上限,分批处理更安全

数据来源与参考

  • MySQL 8.0 Reference Manual · GROUP_CONCAT
  • MySQL 8.0 Reference Manual · Server System Variables · group_concat_max_len
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌