MySQL 中
GROUP BY用于将查询结果按一个或多个字段的值进行分组,使相同值的记录归为一组,通常配合聚合函数(如
COUNT()、
SUM()、
AVG()、
MAX()、
MIN())使用,从而对每组数据进行统计计算。
基本语法与使用规则
GROUP BY必须出现在
WHERE子句之后、
ORDER BY和
LIMIT之前。SELECT 列表中所有**非聚合字段**都必须出现在
GROUP BY子句中(在严格模式下,MySQL 会报错;否则可能返回非确定性结果)。 正确写法:
SELECT dept, COUNT(*) FROM emp GROUP BY dept;错误写法(严格模式下):
SELECT dept, name, COUNT(*) FROM emp GROUP BY dept;——
name未参与分组且未聚合,结果不可靠
常见组合:聚合函数 + GROUP BY
这是最典型的用法,用于统计每组的数量、总和、平均值等。
查每个部门人数:SELECT dept, COUNT(*) AS cnt FROM emp GROUP BY dept;查每个城市的平均薪资:
SELECT city, AVG(salary) AS avg_sal FROM emp GROUP BY city;查每种商品类别的最高价格:
SELECT category, MAX(price) FROM products GROUP BY category;
筛选分组结果:HAVING 子句
WHERE作用于分组前的行,
HAVING作用于分组后的结果,常用来过滤满足条件的组。 查员工数超过5人的部门:
SELECT dept, COUNT(*) FROM emp GROUP BY dept HAVING COUNT(*) > 5;查平均薪资高于8000的城市:
SELECT city, AVG(salary) FROM emp GROUP BY city HAVING AVG(salary) > 8000;注意:
HAVING可以直接使用聚合函数或别名(如
HAVING avg_sal > 8000),但
WHERE不可以
多字段分组与排序
可以按多个字段组合分组,顺序影响分组逻辑;通常搭配
ORDER BY让结果更清晰。 按部门和岗位统计人数:
SELECT dept, job, COUNT(*) FROM emp GROUP BY dept, job;按年份和月份统计订单数,并按年月升序排列:
SELECT YEAR(order_time), MONTH(order_time), COUNT(*) FROM orders GROUP BY YEAR(order_time), MONTH(order_time) ORDER BY 1, 2;注意:ORDER BY 中可用列名、位置序号(如
ORDER BY 1, 2)或别名
掌握
GROUP BY的关键是理解“分组后每组只返回一行”,所有非聚合列必须明确属于该组——要么参与分组,要么通过聚合函数处理。实际写 SQL 时,先想清楚“我要按什么分组?每组要算什么?哪些组需要保留?”就能写出准确可靠的语句。
