SQL的GROUP BY子句用于将查询结果按照一个或多个字段进行分组,再配合聚合函数对每组数据做统计计算,是数据分析场景下的核心语法。除了基础的COUNT、SUM、AVG用法之外,还有很多进阶场景可以提升数据处理效率。

GROUP BY进阶用法场景
1. 分组后筛选:HAVING子句的使用
基础的WHERE子句是在分组前对数据进行筛选,如果需要对分组后的结果做筛选,就需要使用HAVING子句。比如我们需要统计订单表中,总订单金额超过1000的用户信息:
-- 查询总订单金额超过1000的用户ID和总金额 SELECT user_id, SUM(order_amount) AS total_amount FROM order_table GROUP BY user_id HAVING SUM(order_amount) > 1000;
这里需要注意,HAVING子句中可以使用聚合函数,而WHERE子句不支持直接使用聚合函数作为筛选条件。
2. 多字段分组统计
当我们需要按照多个维度同时分组时,可以在GROUP BY后面跟上多个字段,字段之间用逗号分隔。比如统计不同城市不同品类的商品销售总量:
-- 按城市和商品品类分组统计销售总量 SELECT city, category, SUM(sales_num) AS total_sales FROM product_sales GROUP BY city, category ORDER BY city, total_sales DESC;
多字段分组的逻辑是先按照第一个字段分组,再在每个分组内按照第二个字段继续分组,最终得到多维度交叉的统计结果。
3. 聚合函数与CASE WHEN结合使用
有时候我们需要在分组统计时,对不同条件的数据做不同的聚合计算,这时候可以结合CASE WHEN表达式。比如统计每个用户的订单中,已完成订单和未完成订单的数量:
-- 统计每个用户的已完成和未完成订单数
SELECT user_id,
COUNT(CASE WHEN order_status = 'finished' THEN 1 END) AS finished_order_num,
COUNT(CASE WHEN order_status != 'finished' THEN 1 END) AS unfinished_order_num
FROM order_table
GROUP BY user_id;
CASE WHEN表达式会在聚合函数内部先对每条数据做条件判断,再对符合条件的数据做计数,实现分组内的条件统计。
4. 聚合函数嵌套使用
部分场景下我们需要先对分组做一层聚合,再对聚合结果做二次计算,这时候可以使用聚合函数嵌套。比如先统计每个用户的平均订单金额,再计算所有用户的平均订单金额的最大值:
-- 先算每个用户的平均订单金额,再取最大值
SELECT MAX(avg_amount) AS max_user_avg_amount
FROM (
SELECT user_id, AVG(order_amount) AS avg_amount
FROM order_table
GROUP BY user_id
) AS user_avg_table;
这里内层查询先按照用户分组计算平均订单金额,外层查询再对得到的平均金额结果使用MAX聚合函数,得到最终的最大值。
5. GROUP BY配合GROUP_CONCAT拼接分组数据
如果需要将分组内的某个字段的所有值拼接成一个字符串返回,可以使用GROUP_CONCAT函数(MySQL环境),其他数据库也有类似的函数比如STRING_AGG。比如统计每个用户购买过的所有商品名称:
-- 拼接每个用户购买过的所有商品名称,用逗号分隔 SELECT user_id, GROUP_CONCAT(product_name SEPARATOR ',') AS bought_products FROM user_order_product GROUP BY user_id;
GROUP_CONCAT默认用逗号分隔拼接的内容,也可以通过SEPARATOR关键字自定义分隔符,方便后续对拼接结果做处理。
注意事项
- SELECT后面出现的非聚合字段,必须全部出现在GROUP BY子句中,否则查询会报错或者得到不确定的结果。
- HAVING子句和WHERE子句的执行顺序不同,WHERE先执行,HAVING在分组后执行,尽量把可以提前筛选的条件放在WHERE中,减少分组的数据量,提升查询效率。
- 不同数据库的聚合函数语法略有差异,比如SQL Server的拼接函数是STRING_AGG,使用时需要根据实际使用的数据库调整语法。
总结
GROUP BY结合聚合函数的进阶用法可以覆盖大部分复杂的数据分组统计需求,掌握HAVING筛选、多字段分组、条件聚合、函数嵌套等技巧,能够大幅减少数据处理的复杂度,避免多次查询再在应用层做合并计算。在实际使用中,需要根据业务需求选择合适的用法,同时注意不同数据库的语法差异,保证查询的正确性和执行效率。