SQL的多层分组是指按照多个字段的层级关系对数据进行分组统计,能够在一次查询中同时得到不同维度组合的聚合结果,大幅提升数据统计的效率。
多层分组的基本语法
SQL中实现多层分组的核心是使用GROUP BY子句,在子句中依次列出需要分组的字段,字段的顺序决定了分组的层级优先级。基本语法结构如下:
SELECT 分组字段1, 分组字段2, 聚合函数(统计字段) FROM 表名 WHERE 过滤条件 GROUP BY 分组字段1, 分组字段2 ORDER BY 分组字段1, 分组字段2;
其中GROUP BY后面的字段顺序非常重要,先写的字段作为第一层分组维度,后写的字段作为第二层分组维度,依此类推。分组后会先按照第一个字段的相同值归为一组,再在每个大组内按照第二个字段的相同值继续细分小组。
示例演示多层分组效果
假设我们有一张order_table订单表,表结构如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| order_id | INT | 订单ID |
| region | VARCHAR | 地区 |
| category | VARCHAR | 商品类别 |
| amount | DECIMAL | 订单金额 |
现在需要统计每个地区下每个商品类别的订单总数量和总金额,就可以使用两层分组实现,查询语句如下:
SELECT region, category, COUNT(order_id) AS order_count, SUM(amount) AS total_amount FROM order_table GROUP BY region, category ORDER BY region, category;
上述查询的执行逻辑是:首先按照region字段将所有订单划分为不同的地区组,然后在每个地区组内部,再按照category字段划分为不同的商品类别小组,最后对每个小组分别计算订单数量和总金额。
多层分组的注意事项
SELECT子句中出现的非聚合字段,必须全部出现在GROUP BY子句中,否则查询会报错或者得到不符合预期的结果。- 分组字段的顺序会影响分组的结果展示顺序,但不会影响分组的逻辑归属,比如
GROUP BY region, category和GROUP BY category, region得到的小组划分逻辑不同,前者是先按地区再按类别,后者是先按类别再按地区。 - 如果需要对分组后的结果进行过滤,要使用
HAVING子句,而不是WHERE子句,WHERE子句是在分组前对原始数据进行过滤,HAVING是在分组后对聚合结果进行过滤。
比如要筛选总金额超过1000的地区类别组合,查询语句如下:
SELECT region, category, COUNT(order_id) AS order_count, SUM(amount) AS total_amount FROM order_table GROUP BY region, category HAVING SUM(amount) > 1000 ORDER BY region, category;
多层分组的扩展场景
如果需要实现更多层级的分组,只需要在GROUP BY子句中继续添加对应的字段即可,比如要统计每个地区下每个类别下每个用户的订单情况,就可以使用三层分组:
SELECT region, category, user_id, COUNT(order_id) AS order_count, SUM(amount) AS total_amount FROM order_table GROUP BY region, category, user_id ORDER BY region, category, user_id;
多层分组支持的层级数量没有固定限制,只要符合业务统计的维度需求即可,同时可以根据需要搭配不同的聚合函数,比如AVG计算平均值、MAX计算最大值、MIN计算最小值等,满足多样化的统计需求。