group_concat默认用逗号分隔、长度上限1024、不自动去重,超长截断且不报错;需调大group_concat_max_len、用separator指定分隔符、order by控制排序、distinct实现去重。

Group_Concat 能把多行字符串拼成一行,但默认用逗号分隔、长度上限 1024 字符、不自动去重——这三个限制不调就容易丢数据。
为什么 GROUP_CONCAT 返回结果被截断?
MySQL 默认 group_concat_max_len 是 1024,超出部分直接丢弃,且不报错。比如拼接 50 个用户名,每个平均 20 字符,总长超 1000 就可能截断。
- 查当前值:
SELECT @@group_concat_max_len; - 临时改(当前会话):
SET SESSION group_concat_max_len = 1000000; - 永久改需在配置文件
my.cnf加group_concat_max_len = 1000000,然后重启 MySQL - 注意:该变量是 session 级的,
SET GLOBAL不生效,必须用SESSION
如何控制分隔符、排序和去重?
GROUP_CONCAT 支持完整语法:GROUP_CONCAT([DISTINCT] expr [, expr ...] [ORDER BY {unsigned_integer | col_name | expr} [ASC | DESC]] [SEPARATOR str_val]),但顺序不能乱。
- 分隔符用
SEPARATOR ' | '替换默认逗号,注意空格也属于分隔符 - 排序必须写在
SEPARATOR前,例如:GROUP_CONCAT(name ORDER BY id DESC SEPARATOR '; ') - 去重只对单个字段有效:
GROUP_CONCAT(DISTINCT tag SEPARATOR ',');若拼多个字段(如CONCAT(a, '-', b)),去重按整个表达式值判断 - 不能在
GROUP_CONCAT内直接用别名,得写原字段或完整表达式
和 JOIN + 子查询比,性能差在哪?
本质是聚合函数,走的是 GROUP BY 流程,不是字符串拼接优化路径。大数据量时比应用层拼接更慢,尤其带 ORDER BY 或 DISTINCT。
- 索引对
ORDER BY部分字段有效,但只加速排序,不减少扫描行数 - 如果只是简单拼接(无排序、无去重),速度尚可;一旦加
DISTINCT,内部要建临时哈希表,内存压力明显上升 - 替代方案:用应用代码遍历结果集拼接,可控性强,还能流式处理;或者用 JSON 函数(如
JSON_ARRAYAGG)替代,支持 null 安全和嵌套结构
真正麻烦的不是语法,而是它不报错地吞掉超长内容——上线前务必用真实数据量测一次输出长度,别只看测试表三五条记录。











