where必须在group by之前执行,这是sql引擎硬性规定的逻辑顺序;where用于分组前按行过滤原始数据(支持索引、不可用聚合函数),group by则对where筛选后的结果进行分组。

WHERE 先执行,GROUP BY 后执行。这是 SQL 引擎硬性规定的逻辑顺序,不是可选或可调换的。
WHERE 必须在 GROUP BY 之前过滤行
-
WHERE处理的是原始表中的每一行,在分组动作发生前就筛掉不满足条件的数据 - 如果你把本该写在
WHERE的条件错放到GROUP BY后面(比如用HAVING替代),SQL 会多算很多无用分组,性能明显下降 - 常见错误:在
WHERE中使用聚合函数,例如WHERE COUNT(<em>) > 5</em>—— 这会直接报错,因为此时还没分组,COUNT()根本没意义
正确写法示例:
SELECT department, AVG(salary) FROM employees WHERE hire_date >= '2020-01-01' GROUP BY department;
这里先剔除 2020 年前入职的员工,再按部门分组算平均工资。
GROUP BY 依赖 WHERE 的输出结果
-
GROUP BY不会看到被WHERE过滤掉的行,它只对剩下那些行做分组 - 如果
WHERE条件太松(比如漏写关键筛选),GROUP BY就得处理大量无效数据,可能触发内存溢出或超时 - 注意字段可见性:
GROUP BY只能引用FROM/WHERE阶段已存在的列,不能引用SELECT里定义的别名(比如SELECT name AS dept_name,然后GROUP BY dept_name会失败)
容易踩的坑:
-
GROUP BY后的字段必须出现在SELECT列表中,或被聚合函数包裹,否则多数数据库(如 MySQL 严格模式、PostgreSQL)会报错 - MySQL 5.7+ 默认开启
ONLY_FULL_GROUP_BY,禁止“非确定性”分组,这个限制正是为了强制你遵守WHERE → GROUP BY的逻辑链
为什么不能把 WHERE 和 GROUP BY 顺序颠倒?
- 执行顺序不是语法书写顺序,而是引擎实际处理流程
- 即使你把
GROUP BY写在WHERE前面(语法上不允许),SQL 解析器也会拒绝执行 - 真实执行链是:
FROM→WHERE→GROUP BY→HAVING→SELECT→ORDER BY - 想跳过
WHERE直接分组?可以,但代价是:所有行都参与分组计算,哪怕其中 90% 是你要排除的测试数据或历史归档记录
最常被忽略的一点:很多线上慢查询,根源不是索引没建好,而是 WHERE 条件写得太晚——比如本该在 WHERE 过滤掉 80% 行,却错放到了 HAVING,导致数据库先分了几千个组,再一个个判断是否保留。











