`FROM` → `WHERE` → `GROUP BY` → `HAVING` → `SELECT` → `ORDER BY`
2026/7/9 1:47:39 网站建设 项目流程
  • WHERE用于分组前的行级过滤,作用于原始数据行,因此不能使用聚集函数(如COUNT()SUM()AVG()等),因为此时数据尚未分组,聚集函数无意义。

  • HAVING用于分组后的组级过滤,作用于GROUP BY产生的每个分组结果,因此可以且通常需要使用聚集函数来筛选满足条件的分组(例如:HAVING COUNT(*) > 5)。

执行顺序(逻辑顺序,非书写顺序)为:
FROMWHEREGROUP BYHAVINGSELECTORDER BY

📌 示例对比:

-- ✅ 正确:WHERE 过滤单个订单,不涉及聚集SELECTcustomer_id,COUNT(*)FROMordersWHEREorder_date>='2024-01-01'-- 行级条件,合法GROUPBYcustomer_idHAVINGCOUNT(*)>3;-- 组级条件,用聚集函数,合法-- ❌ 错误:WHERE 中使用聚集函数(语法报错)-- WHERE COUNT(*) > 3 -- 不允许!

应该在HAVING中写AVG(salary) > 10000不能在WHERE中写

✅ 正确写法:

SELECTdepartment,AVG(salary)ASavg_salaryFROMemployeesGROUPBYdepartmentHAVINGAVG(salary)>10000;

❌ 错误写法(语法错误):

SELECTdepartment,AVG(salary)FROMemployeesWHEREAVG(salary)>10000-- ❌ 报错:WHERE 无法使用聚集函数GROUPBYdepartment;

🔹 原因如下:

  • WHERE在逻辑执行顺序中位于GROUP BY之前,此时数据尚未按部门分组,每行仍是独立员工记录,AVG(salary)尚未计算(无“部门平均”这一概念),因此 SQL 引擎不允许在WHERE中使用聚集函数。

  • HAVINGGROUP BY之后执行,此时已形成每个部门的一组数据,AVG(salary)可对每组独立计算,因此可安全用于过滤满足条件的部门组。

⚠️ 补充说明:
即使你先用子查询或 CTE 预先算出各部门平均工资,那也是将聚集结果“物化”为普通列后,才可在外层WHERE过滤——但这不改变WHERE本身不能直接调用聚集函数的本质规则。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询