GROUP BY 是 MySQL 中实现分组统计的核心语法,需将分组字段置于 SELECT 列表或聚合函数中,WHERE 在分组前过滤,HAVING 在分组后筛选聚合结果。

在 MySQL 中,GROUP BY 是实现分组统计的核心语法,它能把具有相同值的记录归为一组,再配合聚合函数(如 COUNT、SUM、AVG 等)对每组数据进行计算。关键在于:分组字段必须出现在 SELECT 列表中(除非是聚合函数结果),且 WHERE 在分组前过滤,HAVING 在分组后筛选。
基础用法:按单个字段分组统计
最常见场景是按某列分类汇总。比如统计每个部门的员工人数:
SELECT dept_id, COUNT(*) AS emp_count FROM employees GROUP BY dept_id;
说明:GROUP BY 后跟的字段(dept_id)必须和 SELECT 中的非聚合字段完全一致;COUNT(*) 统计每组行数;结果中每行代表一个 dept_id 及其对应人数。
多字段分组:组合维度更精细
当需要按多个条件联合分组时,直接在 GROUP BY 后列出多个字段,用逗号分隔:
SELECT dept_id, gender, AVG(salary) AS avg_salary FROM employees GROUP BY dept_id, gender;
这样会先按部门分大组,再在每个部门内按性别细分,最终得到“每个部门中每种性别的平均薪资”。注意:SELECT 中所有非聚合列(dept_id、gender)都必须出现在 GROUP BY 子句中。
结合 HAVING 筛选分组结果
WHERE 无法使用聚合函数,所以想“查平均工资超过 8000 的部门”,要用 HAVING:
- WHERE dept_id > 100 —— 分组前过滤原始数据
- HAVING AVG(salary) > 8000 —— 分组后对聚合结果过滤
完整示例:
SELECT dept_id, AVG(salary) AS avg_salary FROM employees WHERE status = 'active' GROUP BY dept_id HAVING AVG(salary) > 8000;
常见错误与注意事项
容易出错的地方包括:
- SELECT 中写了非分组字段又没加聚合函数(MySQL 5.7+ 默认报错)
- 把本该用 HAVING 的条件写在 WHERE 里(如 WHERE COUNT(*) > 5 是非法的)
- ORDER BY 字段未出现在 SELECT 或 GROUP BY 中(建议显式写出,避免歧义)
- 忽略 NULL 值:NULL 在 GROUP BY 中被视为同一组,会被单独分到一组
不复杂但容易忽略










