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 的部分直接丢失,下游解析会拿到不完整数据而日志里看不到任何错误。拼接长文本前先确认上限。