group_concat是mysql专用于分组内字符串聚合的函数,语法为group_concat([distinct] expr [order by ...] [separator str]),默认逗号分隔、长度限1024字节、需显式order by控制顺序。

GROUP_CONCAT 用法和基本写法
MySQL 里合并多行成一行、用逗号隔开,核心就是 GROUP_CONCAT() 函数。它不是普通聚合函数(比如 COUNT() 或 SUM()),而是专门干这事的——把分组内的值拼成字符串。
- 默认以英文逗号
,分隔,不加空格 - 默认只拼前 1024 个字符(受
group_concat_max_len系统变量限制) - 默认按内部顺序拼接,不保证原始查询顺序,如需控制顺序得显式加
ORDER BY
简单例子:查每个部门的员工姓名列表
SELECT dept, GROUP_CONCAT(name) AS names FROM emp GROUP BY dept;
常见错误:结果被截断或显示为 NULL
这是最常遇到的两个坑:
-
GROUP_CONCAT()返回NULL:通常因为分组内所有字段值都是NULL,或者没数据可聚合 - 结果被截断(比如只看到前几个名字):本质是
group_concat_max_len太小,比如默认 1024 字节不够用
解决办法:
- 临时调大长度:
SET SESSION group_concat_max_len = 1000000; - 拼接前过滤空值:
GROUP_CONCAT(IFNULL(name, ''))避免全NULL导致结果为NULL - 显式排除空字符串:
GROUP_CONCAT(name SEPARATOR ',' ORDER BY name) WHERE name != ''(注意WHERE要写在GROUP BY前)
定制分隔符、去重、排序的写法
GROUP_CONCAT() 支持多个修饰子句,但顺序固定:GROUP_CONCAT([DISTINCT] expr [ORDER BY ...] [SEPARATOR str])
-
SEPARATOR后面必须跟字符串字面量,不能是字段或变量,比如SEPARATOR ' | '合法,SEPARATOR sep_col不合法 -
DISTINCT可去重,但要注意它作用于整个表达式,不是单个字段 -
ORDER BY只能在括号内写,且只能引用SELECT列或原表字段,不能用别名(除非用子查询绕过)
示例:去重 + 按 ID 升序 + 用分号隔开
SELECT GROUP_CONCAT(DISTINCT tag ORDER BY id SEPARATOR ';') FROM articles WHERE status = 1;
替代方案:窗口函数或应用层拼接是否更合适?
GROUP_CONCAT() 是 MySQL 特有,跨数据库不兼容;而且它本质是字符串拼接,没法做后续结构化处理(比如 JSON 数组)。
- 如果只是导出报表或前端展示,
GROUP_CONCAT()简单直接 - 如果需要保持类型安全、或后续还要解析成数组,建议应用层(Python/Java 等)做聚合,MySQL 只负责返回明细
- MySQL 8.0+ 可用
JSON_ARRAYAGG()生成 JSON 数组,比字符串更规范,但要确认下游能解析 JSON
注意:GROUP_CONCAT() 在大数据量分组时可能吃内存,尤其 group_concat_max_len 设得过大又没索引支撑,容易拖慢查询。真要拼几千行,先考虑是不是设计上该拆表或加缓存。











