GROUP_CONCAT默认截断超长结果(限1024字符),需调大group_concat_max_len;ORDER BY和SEPARATOR必须写在函数内;非聚合字段须显式出现在GROUP BY中;推荐MySQL 5.7+用JSON_ARRAYAGG替代。

MySQL里GROUP_CONCAT到底怎么用才不丢数据
默认情况下GROUP_CONCAT会截断超长结果,不是bug,是配置限制。它默认只拼前1024个字符,超出部分直接砍掉,还不会报错——你查出来的字符串突然变短、结尾莫名截断,八成是这个原因。
- 先查当前长度限制:
SELECT @@group_concat_max_len; - 临时调高(当前会话有效):
SET SESSION group_concat_max_len = 1000000; - 永久生效需改MySQL配置文件
my.cnf,加一行:group_concat_max_len = 1000000,然后重启服务 - 注意:设太大可能撑爆内存,尤其在大表分组时;建议按实际最大预期长度略留余量,别无脑设99999999
ORDER BY和SEPARATOR必须写在GROUP_CONCAT括号里
GROUP_CONCAT的排序和分隔符不是外部语法,不能像普通ORDER BY那样写在GROUP BY后面。写错位置就完全不生效,或者报语法错误。
- 正确写法:
GROUP_CONCAT(name ORDER BY create_time DESC SEPARATOR ' | ') - 错误写法:
GROUP_CONCAT(name) ORDER BY create_time DESC(这只会对整个分组结果排序,不影响拼接顺序) -
SEPARATOR为空字符串时写SEPARATOR '',不能省略或写NULL,否则默认用逗号 - 如果字段可能为
NULL,它会被忽略;需要显示空值?先用IFNULL(name, '(empty)')包一层
GROUP_CONCAT在非严格模式下可能静默丢行
当SELECT里有GROUP_CONCAT,但其他非聚合字段没出现在GROUP BY中,MySQL 5.7+默认开启ONLY_FULL_GROUP_BY时会直接报错;但如果关了,它会随机选某一行的值填充那些字段——看起来“拼对了”,实则逻辑错乱。
- 检查是否启用:
SELECT @@sql_mode;,看有没有ONLY_FULL_GROUP_BY - 安全写法:所有非聚合字段必须显式出现在
GROUP BY中,哪怕只是GROUP BY id - 别依赖“我试了几次都出得对”——这是未定义行为,换数据、换版本、加索引都可能让结果突变
替代方案:JSON_ARRAYAGG比GROUP_CONCAT更可靠
如果你用的是MySQL 5.7+,且最终目标是传给程序解析(比如PHP/Python),JSON_ARRAYAGG比GROUP_CONCAT更干净:自动处理引号、逗号、换行等特殊字符,不用手动REPLACE转义。
- 简单拼数组:
JSON_ARRAYAGG(name)→["a","b","c"] - 带键值对:
JSON_ARRAYAGG(JSON_OBJECT('id', id, 'name', name)) - 注意:
JSON_ARRAYAGG遇到NULL字段会跳过整条记录,而GROUP_CONCAT只是跳过那个字段——这点差异会影响结果行数 - 性能上两者接近,但
JSON_ARRAYAGG在后续应用层解析成本更低,少一次explode或split

















