GROUPBY基础语法介绍
GROUPBY是sql中用于将数据按照一个或多个列进行分组的子句,分组后可以对每个组的数据进行聚合计算,比如统计每组的数量、求和、求平均值等。基础的分组查询语法结构如下:
SELECT 分组列, 聚合函数(统计列) FROM 表名 WHERE 筛选条件 GROUP BY 分组列 ORDER BY 排序列;

语法各部分说明
SELECT后面除了聚合函数的结果,只能出现GROUP BY中指定的分组列,否则查询结果会不符合预期。WHERE子句用于在分组前筛选原始数据,不符合条件的数据不会进入分组流程。GROUP BY后面可以跟一个或多个列名,多个列时用逗号分隔,会按照列的顺序依次进行分组。ORDER BY是可选部分,用于对最终的查询结果进行排序。
简单分组查询示例
我们先创建一个测试用的订单表,表结构如下:
-- 创建订单表
CREATE TABLE order_info (
order_id INT PRIMARY KEY,
user_id INT,
product_name VARCHAR(50),
order_amount DECIMAL(10,2),
order_date DATE
);
-- 插入测试数据
INSERT INTO order_info VALUES
(1, 101, '手机', 2999.00, '2024-03-01'),
(2, 101, '耳机', 399.00, '2024-03-02'),
(3, 102, '平板', 3999.00, '2024-03-01'),
(4, 103, '手机', 2999.00, '2024-03-03'),
(5, 101, '充电器', 99.00, '2024-03-04'),
(6, 102, '耳机', 399.00, '2024-03-05');
单字段分组统计
如果我们想统计每个用户的订单总数量,就可以用user_id作为分组列,搭配COUNT聚合函数实现:
SELECT user_id, COUNT(order_id) AS order_count FROM order_info GROUP BY user_id;
执行上述语句后,会得到每个用户对应的订单数量,比如用户101有3个订单,用户102有2个订单,用户103有1个订单。
多字段分组统计
如果需要同时按照用户和购买的商品名称分组,统计每个用户购买每种商品的总金额,就可以使用多字段分组:
SELECT user_id, product_name, SUM(order_amount) AS total_amount FROM order_info GROUP BY user_id, product_name;
这个查询会先按照user_id分组,再在每个用户组内按照product_name分组,最终统计出每个用户每种商品的购买总金额。
分组查询的常见注意事项
聚合函数的使用限制
在SELECT子句中,如果没有使用聚合函数,那么出现的列必须全部在GROUP BY子句中声明,否则sql执行会报错。比如下面的写法是错误的:
-- 错误示例:product_name未出现在GROUP BY中 SELECT user_id, product_name, COUNT(order_id) FROM order_info GROUP BY user_id;
分组后筛选使用HAVING
如果需要对分组后的结果进行筛选,不能使用WHERE子句,而是要使用HAVING子句。比如我们想筛选出订单总数量大于2的用户:
SELECT user_id, COUNT(order_id) AS order_count FROM order_info GROUP BY user_id HAVING COUNT(order_id) > 2;
WHERE和HAVING的区别在于,WHERE在分组前筛选数据,HAVING在分组后筛选分组结果。
分组列中的NULL值处理
如果分组列中存在NULL值,所有NULL值会被归为同一个组,这一点在使用GROUP BY时需要特别注意,避免统计结果出现偏差。
实际业务场景应用
在实际的业务场景中,GROUP BY的使用非常广泛,比如统计每个月的销售额、统计每个分类下的商品数量、统计每个地区的用户活跃度等。只要是需要按照某个维度对数据进行归类统计的需求,都可以优先考虑使用GROUP BY配合聚合函数实现。
掌握GROUP BY的基础用法后,还可以进一步学习GROUP BY和ROLLUP、CUBE等扩展功能的搭配使用,实现更复杂的层级分组统计需求。