Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQL语句中having的执行顺序是在select之前吧 #2369

Open
mx5518 opened this issue Apr 18, 2024 · 3 comments
Open

SQL语句中having的执行顺序是在select之前吧 #2369

mx5518 opened this issue Apr 18, 2024 · 3 comments

Comments

@mx5518
Copy link

mx5518 commented Apr 18, 2024

在SQL常见面试题总结1中,计算总和这部分的sql语句
SELECT order_num, Sum(item_price * quantity) AS total_price
FROM OrderItems
GROUP BY order_num
HAVING total_price >= 1000
ORDER BY order_num
SQL语句中having的执行顺序是在select之前吧,所以having中不能写total_price吧

@yuexin1028
Copy link

在实际执行时,SQL查询的大致流程如下:

  1. FROM子句确定基本的数据来源表。
  2. WHERE子句对从FROM子句中获取的数据进行行级别的过滤。
  3. GROUP BY子句对数据进行分组。
  4. HAVING子句基于每个组应用过滤条件,此时是可以使用SELECT列表中定义的别名的,因为在这个阶段,SQL引擎已经知道了每个组的聚合值。
  5. SELECT子句选择并计算每个组的聚合值或其他列,这里的Sum(item_price * quantity) AS total_price就是这样的一个计算。
  6. ORDER BY子句对结果集进行排序。

因此,在上述SQL语句中,total_price别名在HAVING子句中是合法的,因为SQL引擎会在应用HAVING过滤条件之前计算出这个总价格。

@fox-half-tian
Copy link
Contributor

我最近在一家公司实习,在熟悉项目的过程中,看到了很多这样的写法,一开始我也是真的蒙了,以前没讲过,因为我在学习的时候老师也是说的不要在 having 中以未聚合的字段作为条件过滤,后来查资料才发现可以提前在 select 中进行聚合,指定别名在 having 中使用。这两种写法有什么效率上的差别吗,有大佬可以解释一下吗

@CONTINUE12
Copy link

按照标准SQL规范来讲,一条SQL语句的执行顺序是这样的:
from
join
on
where
group by
having
select
distinct
order by
limit
根据这个标准having会在select之前执行,所以在having中使用select定义的别名会报错。
但是现在很多数据库都对此做了扩展,例如MySQL、SQLLite等都支持having使用聚合之后的别名。
因此具体使用时以数据库的种类和版本规范为准。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants