MySQL中GROUP_CONCAT函数详解 | 按日期分组拼接销售产品经典案例

前言

在日常的SQL业务开发中,我们经常遇到分组统计+分组内字段拼接 的需求,比如按日期统计每日销售的产品数量、并将当日销售的所有产品名称拼接成一个字符串展示。这类需求用普通的GROUP BY分组+聚合函数是无法实现的,而MySQL的GROUP_CONCAT()函数就是专门解决这类场景的「神器」,今天结合经典的「按日期分组统计销售产品」SQL案例,彻底吃透GROUP_CONCAT()的用法和核心细节。

一、先看完整业务场景SQL(经典面试/业务题)

需求说明

现有销售记录表Activities,表中核心字段为sell_date(销售日期)、product(销售产品名),要求:

  1. 按销售日期进行分组
  2. 统计每日不同产品的销售数量
  3. 展示每日销售的所有不同产品名称,产品名称按字母升序排列、用英文逗号分隔
  4. 最终结果按销售日期升序排序

实现SQL

sql 复制代码
select
    sell_date,
    count(distinct product) as num_sold, -- 统计每日售卖的不同产品数
    group_concat(distinct product order by product separator ',') as products -- 拼接每日售卖的产品名
from
    Activities
group by
    sell_date -- 核心:按日期分组
order by
    sell_date ASC;

二、GROUP_CONCAT() 函数核心介绍

✅ 函数定义

GROUP_CONCAT() 是MySQL专属的分组聚合函数 ,作用是:将分组后的同一组内的指定字段的所有值,拼接成一个完整的字符串返回

✅ 函数核心语法格式

sql 复制代码
GROUP_CONCAT([DISTINCT] 字段名 [ORDER BY 字段排序规则] [SEPARATOR '分隔符'])

✅ 语法各部分解析(重中之重,全部常用)

1. 必选核心:GROUP_CONCAT(字段名)

最基础用法,无任何修饰,直接拼接分组内指定字段的所有值。

  • 特点:会保留字段的重复值
  • 拼接分隔符:默认使用 英文逗号, 分隔
  • 排序:默认按字段值的自然顺序排序,无指定规则
2. 核心修饰1:DISTINCT 去重关键字
sql 复制代码
GROUP_CONCAT(DISTINCT 字段名)

这是业务中极高频的用法 ,作用是:对分组内要拼接的字段值先去重,再拼接

比如本文案例中,同一天可能同一个产品卖出多次,我们只需要展示「当日卖了哪些产品」,而非「每次卖出的产品」,所以必须加DISTINCT product,避免产品名重复拼接。

3. 核心修饰2:ORDER BY 排序子句
sql 复制代码
GROUP_CONCAT(字段名 ORDER BY 字段名 [ASC/DESC])

作用是:对分组内要拼接的字段值,按照指定规则排序后再拼接

比如本文案例中要求产品名按字母升序排列,所以写order by product(默认ASC升序,可省略),如果需要降序则写order by product DESC

4. 核心修饰3:SEPARATOR '分隔符' 分隔符指定
sql 复制代码
GROUP_CONCAT(字段名 SEPARATOR '自定义分隔符')

作用是:指定拼接后的分隔符,替换默认的英文逗号

  • 支持任意自定义分隔符:逗号,、竖线|、横线-、空格 、分号;

比如本文案例指定用英文逗号分隔,所以写separator ',',这也是最常用的分隔符。

✅ 完整组合用法(案例同款,开发中最常用)

sql 复制代码
GROUP_CONCAT(DISTINCT 字段名 ORDER BY 字段名 SEPARATOR '分隔符')

先去重 → 再排序 → 最后按指定分隔符拼接,完美解决绝大多数分组拼接需求。

三、GROUP_CONCAT() 核心注意事项(避坑必备)

✅ 注意1:必须配合 GROUP BY 使用,否则无意义

GROUP_CONCAT()分组聚合函数 ,和COUNT()SUM()MAX()等函数的特性一致:

  • 如果有GROUP BY,则按分组维度拼接每组的字段值
  • 如果没有GROUP BY,则整张表视为「一个分组」,会把指定字段的所有值拼接成一个字符串

切记:该函数不能脱离分组场景单独使用,否则业务逻辑一定错误。

✅ 注意2:默认有长度限制,超出会被截断

这是最容易踩坑的点 ,MySQL对GROUP_CONCAT()的返回结果,默认有最大长度限制 1024 字节

  • 如果分组内要拼接的内容过多(比如一个分组有上百个产品名),拼接后的字符串长度超过1024字节,超出部分会被直接截断,导致返回结果不完整。
✅ 解决方案:修改长度限制(两种方式)
方式1:临时修改(当前会话有效,重启MySQL失效)
sql 复制代码
-- 设置全局的拼接长度限制,建议设置为合适的值,比如102400(100KB)
SET GLOBAL group_concat_max_len = 102400;
-- 设置当前会话的拼接长度限制
SET SESSION group_concat_max_len = 102400;
方式2:永久修改(修改配置文件,推荐生产环境使用)

编辑MySQL的配置文件my.cnf(Linux)或my.ini(Windows),在[mysqld]节点下添加配置:

ini 复制代码
[mysqld]
group_concat_max_len = 102400

添加后重启MySQL服务,配置永久生效。

✅ 注意3:与 CONCAT() 的区别,千万不要混淆

很多初学者会把GROUP_CONCAT()CONCAT()搞混,这两个函数完全不同,用途天差地别,这里做清晰区分,杜绝混淆:

  1. CONCAT(字段1,字段2,...)行级拼接 ,作用于「单行数据」,将同一行的多个字段值拼接成一个字符串,不分组、聚合相关
    • 例:CONCAT(name, '-', price) → 把单行的姓名和价格拼接成「张三-99」
  2. GROUP_CONCAT(字段)分组拼接 ,作用于「分组后的多行数据」,将同一分组的多行的同一个字段 值拼接成一个字符串,必须分组、属于聚合函数
    • 例:本文案例中,把「2026-01-20」这个分组的所有产品名拼接成「苹果,香蕉,橙子」

✅ 一句话总结区别:CONCAT是同行多字段拼接,GROUP_CONCAT是同组同字段多行拼接

四、拓展:常见衍生用法

✅ 用法1:拼接多个字段+自定义分隔符

如果需要在分组内,拼接「产品名+价格」这类多个字段的组合值,可以嵌套CONCAT()使用:

sql 复制代码
select
    sell_date,
    group_concat(DISTINCT CONCAT(product, '-', price) ORDER BY product separator ';') as product_price
from Activities
group by sell_date;

效果:拼接出「苹果-5.9;香蕉-3.9;橙子-4.5」这样的组合字符串。

✅ 用法2:结合其他聚合函数使用

COUNT(DISTINCT)SUM()等聚合函数完美兼容,也是本文案例的写法,这是业务开发中的标配:

sql 复制代码
select
    sell_date,
    count(distinct product) as 销售产品数,
    sum(amount) as 当日销售额,
    group_concat(distinct product order by product) as 销售产品列表
from Activities
group by sell_date;

五、总结

✅ 核心知识点

  1. GROUP_CONCAT()是MySQL分组聚合函数,作用是分组拼接同组字段值为字符串
  2. 完整语法:GROUP_CONCAT([DISTINCT] 字段 [ORDER BY 字段] [SEPARATOR '分隔符'])
  3. 三大核心修饰:DISTINCT去重、ORDER BY排序、SEPARATOR指定分隔符,可组合使用;
  4. 必须配合GROUP BY使用,否则无分组意义;
  5. 默认长度限制1024字节,超长需手动修改配置;
  6. CONCAT()的核心区别:分组多行单字段拼接 vs 单行多字段拼接。

✅ 业务适用场景

除了本文的「按日期分组拼接销售产品」,该函数还适用于所有需要分组聚合+内容拼接的场景:

  • 按用户分组,拼接用户所有的下单商品;
  • 按班级分组,拼接班级所有的学生姓名;
  • 按部门分组,拼接部门所有的员工工号;
  • 按订单分组,拼接订单所有的商品规格。

GROUP_CONCAT()是MySQL开发中非常实用的函数,掌握其用法和避坑点,能极大提升我们处理分组拼接类需求的效率,希望本文的讲解能帮助大家彻底吃透这个函数!


博主留言

如果本文对你有帮助,欢迎点赞+收藏+关注!后续会持续更新MySQL高频函数和经典业务SQL案例,一起夯实数据库基础,高效开发~

相关推荐
key1s2 小时前
在 clickhouse时间降序排序解决方案
数据库
有梦想有行动2 小时前
ClickHouse的Partition和Part概念
linux·数据库·clickhouse
GZ_TOGOGO2 小时前
Oracle数据库考试适合哪些人
数据库·oracle·数据库开发·ocp认证·2026年it学习
Gauss松鼠会2 小时前
【openGauss】学习 gsql 命令行的使用
数据库·sql·database·opengauss
晓13132 小时前
第二章:Redis常见命令与Java客户端
java·数据库·redis
·云扬·2 小时前
MySQL索引实战指南:添加场景、联合索引要点与失效场景解析
数据库·mysql
填满你的记忆2 小时前
【从零开始——Redis 进化日志|Day7】双写一致性难题:数据库与缓存如何不再“打架”?(附 Canal/读写锁实战)
java·数据库·redis·缓存·面试
小白考证进阶中2 小时前
MySQL OCP认证可以考中文?备考难度怎么样?
数据库·mysql·dba·数据库管理·开闭原则·数据库管理员·mysql认证
蒟蒻的贤3 小时前
操作系统复习
java·开发语言·数据库