在SQL SELECT语句中,HAVING和WHERE的区别是什么?

编辑:我已经把Steven的答案标记为正确答案,因为它包含了链接上的关键信息:

当GROUP BY没有被使用时,HAVING就像一个WHERE子句

我在WHERE中看到的情况没有GROUP BY,这就是我的困惑开始的地方。当然,在你知道这一点之前,你不能在问题中指定它。


当前回答

对我来说,第一个区别是:如果HAVING从SQL语言中移除,那么生活将或多或少地像以前一样。当然,少数查询需要使用派生表、CTE等重新编写,但它们可能会因此更容易理解和维护。也许供应商的优化器代码需要重新编写,以考虑到这一点,这又是一个行业内改进的机会。

Now consider for a moment removing WHERE from the language. This time the majority of queries in existence would need to be rewritten without an obvious alternative construct. Coders would have to get creative e.g. inner join to a table known to contain exactly one row (e.g. DUAL in Oracle) using the ON clause to simulate the prior WHERE clause. Such constructions would be contrived; it would be obvious there was something was missing from the language and the situation would be worse as a result.

我们可能失去明天的“拥有”,情况不会更糟,甚至可能更好,但“在哪里”就不一定了。


从这里的答案来看,许多人似乎没有意识到HAVING子句可以在没有GROUP BY子句的情况下使用。在本例中,HAVING子句应用于整个表表达式,并要求SELECT子句中只出现常量。通常,HAVING子句将涉及聚合。

这比听起来更有用。例如,考虑这个查询来测试name列是否对T中的所有值都是唯一的:

SELECT 1 AS result
  FROM T
HAVING COUNT( DISTINCT name ) = COUNT( name );

只有两种可能的结果:如果HAVING子句为真,则结果为包含值1的单行,否则结果为空集。

其他回答

我使用HAVING来约束基于聚合函数结果的查询。例如:select * in blahblahblah group by SOMETHING having count(SOMETHING)>0

WHERE子句不适用于聚合函数 意思是:你不应该这样使用 附赠:表名

SELECT name  
FROM bonus  
GROUP BY name  
WHERE sum(salary) > 200  

不要用WHERE从句,而要用HAVING..

如果不使用GROUP BY子句,HAVING子句就相当于WHERE子句

SELECT name  
FROM bonus  
GROUP BY name  
HAVING sum(salary) > 200  

在聚合查询中(使用聚合函数的任何查询),Where子句中的谓词在生成聚合中间结果集之前求值,

Having子句中的谓词在聚合结果集生成后应用于聚合结果集。这就是为什么聚合值的谓词条件必须放在Having子句中,而不是放在Where子句中,以及为什么可以在Having子句中使用Select子句中定义的别名,而不能在Where子句中使用。

的搜索条件 group或在SELECT语句中使用的聚合函数。

对我来说,第一个区别是:如果HAVING从SQL语言中移除,那么生活将或多或少地像以前一样。当然,少数查询需要使用派生表、CTE等重新编写,但它们可能会因此更容易理解和维护。也许供应商的优化器代码需要重新编写,以考虑到这一点,这又是一个行业内改进的机会。

Now consider for a moment removing WHERE from the language. This time the majority of queries in existence would need to be rewritten without an obvious alternative construct. Coders would have to get creative e.g. inner join to a table known to contain exactly one row (e.g. DUAL in Oracle) using the ON clause to simulate the prior WHERE clause. Such constructions would be contrived; it would be obvious there was something was missing from the language and the situation would be worse as a result.

我们可能失去明天的“拥有”,情况不会更糟,甚至可能更好,但“在哪里”就不一定了。


从这里的答案来看,许多人似乎没有意识到HAVING子句可以在没有GROUP BY子句的情况下使用。在本例中,HAVING子句应用于整个表表达式,并要求SELECT子句中只出现常量。通常,HAVING子句将涉及聚合。

这比听起来更有用。例如,考虑这个查询来测试name列是否对T中的所有值都是唯一的:

SELECT 1 AS result
  FROM T
HAVING COUNT( DISTINCT name ) = COUNT( name );

只有两种可能的结果:如果HAVING子句为真,则结果为包含值1的单行,否则结果为空集。