You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于SQL执行顺序的疑问:AVG(Amount)的执行时机

SELECT First_name,last_name,email,ROUND (AVG(Amount),2) AS moneyspent
FROM Customer INNER JOIN Payment
ON Customer.customer_id= Payment.customer_id
WHERE Staff_id=2 
GROUP BY First_name,last_name,email
HAVING SUM(Amount)>100
ORDER BY Moneyspent DESC

查询结果

first_namelast_nameemailmoneyspent
BrittanyRileybrittany.riley@sakilacustomer.org5.83
ArnoldHavensarnold.havens@sakilacustomer.org5.14
EleanorHunteleanor.hunt@sakilacustomer.org5.04
StaceyMontgomerystacey.montgomery@sakilacustomer.org4.73
KarlSealkarl.seal@sakilacustomer.org4.63

疑问

我对SQL的执行顺序存在疑问。我理解无法在WHERE子句中基于AVG(Amount)这类聚合结果进行过滤,因为此时聚合操作尚未执行。现请教:AVG(Amount)是在GROUP BY阶段还是SELECT阶段执行?

  1. 若在GROUP BY阶段执行,此时应剩下First_name、Last_name、email和AVG(Amount)这几列,为何HAVING SUM(AMOUNT)仍能执行?
  2. 若在SELECT阶段执行,由于HAVING在SELECT之前执行,为何还能在HAVING中使用AVG(Amount)进行过滤?

解答

首先明确:聚合函数(如AVG、SUM)是在GROUP BY分组完成后、HAVING过滤之前统一计算的,不属于单纯的GROUP BY或SELECT阶段。

SQL的逻辑执行顺序可简化为:

  1. FROM/JOIN:关联表获取原始数据集
  2. WHERE:过滤原始数据行(此时未分组,无法使用聚合函数)
  3. GROUP BY:按指定字段对过滤后的数据分组
  4. 计算所有聚合值:对每个分组,一次性算出所有需要的聚合结果(不管是SELECT还是HAVING中用到的)
  5. HAVING:用已计算好的聚合值过滤分组
  6. SELECT:选择需要的字段(分组字段+已计算的聚合值)
  7. ORDER BY:对最终结果排序

针对你的两个问题:

  • 问题1:GROUP BY仅完成分组操作,之后会计算所有涉及到的聚合函数(包括SELECT里的AVG(Amount)和HAVING里的SUM(Amount)),并非只计算SELECT中声明的聚合值,所以HAVING能正常调用SUM(Amount)进行过滤。
  • 问题2:聚合函数的计算早于HAVING的执行,当HAVING运行时,每个分组的AVG(Amount)结果已经生成,自然可以用它来过滤分组。

内容的提问来源于stack exchange,提问作者Kartik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 18:52:54