SQL是先运行select还是先运行having子句?

SQL语句中到底是先select执行后having还是先having执行再select执行呢?如下图所示,这是表数据:

然后这是代码及运行结果:

网上的答案是先执行having后执行select,但是上面第二幅图不是先在select中指定了“sum(num) as all_num”后,才能运行“having all_num > 50”吗,不然怎么会运行成功呢?我的疑问是如果是先havingselect的话,你哪里来的all_numhaving执行呢?不是应该先select查询出结果才有all_num,再运行having子句吗?

希望有人能解答我的疑惑

阅读 1k
avatarAI BotBETA

答案

在SQL查询中,SELECTHAVING子句的执行顺序并不是按照字面上的顺序来执行的。实际上,SELECTHAVING子句的逻辑执行顺序是:

  1. FROMJOIN(确定数据来源和如何联接它们)
  2. WHERE(对从FROMJOIN得到的记录进行过滤)
  3. GROUP BY(对过滤后的记录进行分组)
  4. 聚合函数(如SUM())在GROUP BY之后计算
  5. HAVING(对分组后的聚合结果进行过滤)
  6. SELECT(选择需要的列,包括聚合函数的结果)

所以,虽然SELECT子句在SQL语句中出现在HAVING子句之前,但在逻辑执行顺序上,聚合函数(如SUM(num) as all_num)的计算是在HAVING子句过滤之前完成的。

在你提供的例子中,SUM(num) as all_num这个聚合计算是在HAVING all_num > 50之前完成的。换句话说,SQL先计算所有组的num字段之和,然后给这个结果起个别名all_num,接着使用这个all_num的结果去过滤那些和大于50的组。

因此,尽管SELECTHAVING在SQL语句中的位置看起来像是先SELECTHAVING,实际上聚合函数(在SELECT中定义)的计算和HAVING过滤是在一个逻辑阶段完成的,这个逻辑阶段在SELECT列选择之后。这意味着,在逻辑上,SQL会先计算聚合结果,然后再使用HAVING子句来过滤这些聚合结果。

希望这个解释能够解答你的疑惑。

2 个回答
但是上面第二幅图不是先在select中指定了“sum(num) as all_num”后,才能运行“having all_num > 50”吗,不然怎么会运行成功呢?

你说的没错,我觉得你只是混淆了select的作用。这里的select的意思是做完having子组筛选后把结果选择出来展示,而不是对数据作操作拿给having去做子组筛选
我们理一下顺序:
1.group by先分组
2.sum()聚合函数执行算出每个组的总和(它不依赖于select这个动作)
3.having子句对子组总和结果作筛选
4.select把结果选择性展示出来

AI Bot 给出的答案应该是对的
FROM -> GROUP BY -> SUM -> HAVING -> SELECT

image.png

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏