"HAVING ... GROUP BY"和"GROUP BY ... HAVING"之间的区别

6

我有一个名为MYTABLE的表格,它有两列:AB

我有以下代码片段:

SELECT MYTABLE.A FROM MYTABLE 
    HAVING SUM(MYTABLE.B) > 100
    GROUP BY MYTABLE.A

并且

SELECT MYTABLE.A FROM MYTABLE 
    GROUP BY MYTABLE.A
    HAVING SUM(MYTABLE.B) > 100

这两个代码是否相同?这两个代码可能会返回不同的结果集吗?

提前感谢您。


6
你尝试过吗?我不知道有哪个数据库管理系统支持你的第一个查询语句。 - GarethD
1
区别在于第一个会失败,而第二个不会。 - user330315
1
至少我们看到sqlfiddle将其吞下并且没有任何抱怨 http://www.sqlfiddle.com/#!4/9090b/2 - DrCopyPaste
3
好的,现在我知道一个DBMS可以接受第一种语法了。每天都是学习的日子。 - GarethD
5个回答

9
根据文档记录,实际上没有区别。人们只是习惯在 GROUP BY 后看到 HAVING。请参考此链接。在 where_clause 和 hierarchical_query_clause 后指定 GROUP BY 和 HAVING。如果同时指定 GROUP BY 和 HAVING,则它们可以以任何顺序出现。你也可以查看这个示例

2

我最初的写法是:

我不确定你的第一个查询是否有效。据我所知,HAVING应该始终位于GROUP BY之后。

我被David Aldridge纠正了,Oracle文档表明顺序并不重要。虽然出于可读性和防止与WHERE子句混淆的原因,我不建议在GROUP之前使用HAVING,但从技术上讲是正确的。这意味着你的问题的答案是“是的,它是相同的”。


http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_10002.htm#SQLRF20040 - David Aldridge
谢谢您的纠正,我不知道这一点。虽然从词汇上看,它似乎是一个愚蠢的顺序。 :) 我会编辑我的答案。 - M-Peror
这似乎很奇怪,但我认为大多数是因为不熟悉。如果你仔细想想,FROM子句先出现其实很有道理 - 至少我通常都是这样开始编写复杂的SQL语句的。 - David Aldridge
同意,把FROM放在前面确实更有意义。略微离题:我听说这是MS设计LINQ时让FROM子句首先出现的实际原因(当然很多灵感来自SQL)。他们不得不这样做,否则在IDE中几乎不可能使代码完成等功能正常工作。 - M-Peror
此外,改变事物会让它们看起来更好,否则为什么要改变它们呢? - David Aldridge

0

子句按顺序进行评估。您可以在FROM子句后立即使用HAVING子句。在这种情况下,HAVING子句将应用于结果集的整个行。在此情况下,选择列表可能仅包含HAVING子句中包含的一个/多个/所有聚合函数。

因此,由于上述原因,您的第一个查询无效。有效的查询将是

SELECT SUM(MYTABLE.B) AS s FROM MYTABLE 
HAVING SUM(MYTABLE.B) > 100

以上查询将返回一行或零行,具体取决于条件SUM(MYTABLE.B) > 100是否被验证。

但是,你的第一个查询还有另一个原因不合法。GROUP BY子句只能引用适用于其的数据集中的列。因此,继续使用上面有效的查询,您可以编写以下有效的查询(尽管它将是无用和荒谬的,因为它仅适用于一行或零行):

SELECT SUM(s)
FROM 
(
SELECT SUM(MYTABLE.B) s
FROM MYTABLE 
HAVING SUM(MYTABLE.B) > 100
) q
GROUP BY s

所以,简单回答一下:不,它们不相同。其中一个甚至都不是有效的。

我不知道你为什么这样想。文档记录了这两个子句可以以任何顺序出现,并且代码可以正常工作。http://sqlfiddle.com/#!4/66e33/1 - David Aldridge
实际上,它看起来是依赖于供应商的。因此我们不能在这里谈论标准SQL。我的答案已经经过测试,并且适用于SQL Server 2008 R2。确实,Oracle支持您提供的fiddle中的语法。 - Andrei Nicusan

0

WHERE和HAVING都允许在查询中设置条件。区别在于: 我们使用WHERE来筛选从表中返回的记录, 我们使用HAVING来筛选从GROUP BY SELECT查询返回的分组。


0

GROUP BY之前不能有HAVINGHAVING就像WHERE一样,但是用于GROUP BY条件。


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