如何分组查询数据_mysql group by操作

来源:这里教程网 时间:2026-02-28 20:33:42 作者:

MySQL 中的 GROUP BY 用于将查询结果按一个或多个字段进行分组,配合聚合函数(如 COUNT()、SUM()、AVG()、MAX()、MIN())统计每组的数据。它不是简单“分组”,而是“先分组、再聚合”,理解这一点是正确使用的前提。

基础语法与核心逻辑

GROUP BY 必须出现在 WHERE 子句之后、ORDER BY 之前;SELECT 列表中所有非聚合字段都必须出现在 GROUP BY 子句中(SQL 标准要求,MySQL 5.7+ 默认开启

ONLY_FULL_GROUP_BY
模式后强制校验)。

✅ 正确写法:
SELECT dept, COUNT(*) FROM emp GROUP BY dept;
❌ 错误写法:
SELECT dept, name, COUNT(*) FROM emp GROUP BY dept;
(name 不在 GROUP BY 中,也不聚合,会报错)
? 小技巧:若想查每组中某条记录(如最新一条),不能只靠 GROUP BY,需结合子查询、窗口函数(MySQL 8.0+)或 JOIN 处理。

多字段分组与组合统计

按多个字段分组时,MySQL 将“字段值完全相同”的记录归为一组,适合分析交叉维度数据。

例如统计“每个部门每种职位的人数”:
SELECT dept, job, COUNT(*) FROM emp GROUP BY dept, job;
注意顺序不影响分组逻辑,但影响结果排序(除非显式加 ORDER BY) 可对分组结果进一步筛选,用 HAVING(不是 WHERE)——WHERE 过滤行,HAVING 过滤组。

HAVING 过滤分组结果

HAVING 在分组和聚合计算完成后执行,用于筛选满足条件的组;WHERE 无法使用聚合函数,但 HAVING 可以。

查人数超过 2 人的部门:
SELECT dept, COUNT(*) FROM emp GROUP BY dept HAVING COUNT(*) > 2;
查平均工资高于 8000 的部门:
SELECT dept, AVG(salary) FROM emp GROUP BY dept HAVING AVG(salary) > 8000;
WHERE + HAVING 可共存:WHERE 先过滤原始数据(如
WHERE status='active'
),再分组,最后 HAVING 筛组。

常见误区与注意事项

GROUP BY 容易因理解偏差导致结果异常或报错。

⚠️ 不要依赖 MySQL 旧版本的“隐式 GROUP BY”行为(如 SELECT id, name, COUNT(*) GROUP BY dept),该写法不标准且在严格模式下失败。 ⚠️ 聚合函数作用于每组内部,不是全表。比如
MAX(salary)
返回的是每组最高薪,不是整张表最大值。
✅ 排序建议显式写:
ORDER BY COUNT(*) DESC
,避免依赖默认顺序。
✅ MySQL 8.0+ 推荐用窗口函数替代部分复杂分组需求,如
ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC)
查各部门最高薪员工。

相关推荐