Oracle - 为什么HAVING子句可以放在GROUP BY之前?

4

为什么/如何HAVING子句可以在GROUP BY之前使用

select count(1) from tableA
having id >1
group by id
order by count(1)

我知道HAVING子句可以不用GROUP BY子句,

但是,在定义GROUP BY时,为什么HAVING不像ORDER BY子句一样被强制放在后面呢?

德比数据库按以下顺序处理SelectExpression:

  • FROM子句
  • WHERE子句
  • GROUP BY(或隐式GROUP BY)
  • HAVING子句
  • ORDER BY子句

在所有文档中,它都出现在GROUP BY之后:

GROUP BY WORKDEPT 
HAVING MAX(SALARY) < (SELECT AVG(SALARY)
                         FROM EMPLOYEE
                         WHERE NOT WORKDEPT = EMP_COR.WORKDEPT)

编辑 Oreilly 的文章中指出,顺序不重要(但没有解释为什么)

在SELECT语句中,GROUP BY子句和HAVING子句的顺序并不重要。我们可以先指定GROUP BY子句再指定HAVING子句,或者反过来。

我怀疑是因为HAVING子句可以没有GROUP BY子句,所以顺序不强制执行。


这一定是重载的 HAVING 子句,类似于 MySQL。您的 HAVING 子句实际上被评估为一个 WHERE 子句。 - Tim Biegeleisen
@TimBiegeleisen 似乎是HAVING子句在执行GROUP BY之后。 - user7294900
对于对 id 的限制,这并不重要,因为这也是您正在分组的列。在进行 GROUP BY 后抛弃整个组,或在 GROUP BY 之前抛弃该组中的所有记录都是一样的。 - Tim Biegeleisen
从逻辑上讲,我同意having应该在group by之后。但是,如果你愿意,你也可以反过来写。 - William Robertson
1个回答

1
由于having子句作用于结果(过滤select的结果),因此查询选择只能基于select,或者如果是聚合查询,则结果在GROUP BY之后生成。这样,语义上HAVING被放置在查询CLAUSE的末尾..就在呈现CLAUSE(ORDER BY)之前。

1
这不是完整的答案,没有提供文档参考等。 - Tim Biegeleisen
这个链接指向一个叫做“Java DB”的东西。不管它是什么,它似乎具有与普通的Oracle SQL相同的语法。 - William Robertson
1
@WilliamRobertson - "Java DB" 是 Oracle 发布的 Apache Derby 的发行版,它是一个用 Java 编写的关系型数据库。如果我没记错,Derby(最初称为 JBMS;也称为 Cloudscape)的语句语法(但不包括数据类型)是模仿 Oracle 设计的。 - Bob Jarvis - Слава Україні

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接