提问人:Kartik 提问时间:6/13/2023 最后编辑:Laurenz AlbeKartik 更新时间:6/13/2023 访问量:52
执行顺序混乱
order of execution confusion
问:
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_name | last_name | 电子邮件 | 花的钱 |
---|---|---|---|
布列塔尼 | 莱利 | [电子邮件保护] | 5.83 |
阿诺德 | 天堂 | [电子邮件保护] | 5.14 |
埃莉 诺 | 打猎 | [电子邮件保护] | 5.04 |
史黛西 | 蒙哥马利 | [电子邮件保护] | 4.73 |
卡尔 | 密封 | [电子邮件保护] | 4.63 |
我对执行顺序感到困惑。我知道我们不能根据聚合结果进行过滤,因为尚未执行。是否发生在 或 ?AVG(Amount)
WHERE
AVG(Amount)
GROUP BY
SELECT
如果它发生在 ,则应该有三列 、 和 left。怎么还能执行?
GROUP BY
First_name
Last_name
email
AVG(Amount)
HAVING SUM(AMOUNT)
如果它发生在 ,那么为什么我们仍然可以像以前一样使用 at 进行过滤?
SELECT
AVG(Amount)
HAVING
HAVING
SELECT
答:
在处理您的查询时,执行引擎还将评估(以及)每个first_name、last_name、电子邮件组合;因为这些分别由您的 SELECT 和 HAVING 引用。一些RDBMS不允许引用SELECT子句中尚未出现的表达式,但我想PostgreSql正在帮我们一个忙并允许它。出于您的目的,您应该假设这些聚合是在 GROUP BY 时间计算的(之后应用了 HAVE;但这实际上是一个“逻辑”顺序,因为如果引擎推断出它会更便宜并且不会改变结果,它可以更早地应用其中的一部分)。GROUP BY
SUM(Amount)
AVG(Amount)
HAVING
评论
在考虑结果时,可以认为 and 子句在子句之前进行了计算,但列定义中使用的任何聚合函数仍然可以访问基础的分解数据。GROUP BY
HAVING
SELECT
SELECT
考虑它的顺序是:
JOIN
s 和子句WHERE
GROUP BY
;请注意,但是,您也可以在输出查询中按列分组,例如 但这是合糖GROUP BY 1, 2
HAVING
SELECT
您可以看到,结果列的实际计算发生在最后,因为如果将窗口函数用作访问(例如)上一行的一部分,则只能访问已包含在其中或使用聚合函数的数据,并且 or 子句删除的数据将被过滤掉。SELECT
GROUP BY
HAVING
WHERE
评论