在SQL SELECT语句中,HAVING和WHERE的区别是什么?
编辑:我已经把Steven的答案标记为正确答案,因为它包含了链接上的关键信息:
当GROUP BY没有被使用时,HAVING就像一个WHERE子句
我在WHERE中看到的情况没有GROUP BY,这就是我的困惑开始的地方。当然,在你知道这一点之前,你不能在问题中指定它。
在SQL SELECT语句中,HAVING和WHERE的区别是什么?
编辑:我已经把Steven的答案标记为正确答案,因为它包含了链接上的关键信息:
当GROUP BY没有被使用时,HAVING就像一个WHERE子句
我在WHERE中看到的情况没有GROUP BY,这就是我的困惑开始的地方。当然,在你知道这一点之前,你不能在问题中指定它。
当前回答
在聚合查询中(使用聚合函数的任何查询),Where子句中的谓词在生成聚合中间结果集之前求值,
Having子句中的谓词在聚合结果集生成后应用于聚合结果集。这就是为什么聚合值的谓词条件必须放在Having子句中,而不是放在Where子句中,以及为什么可以在Having子句中使用Select子句中定义的别名,而不能在Where子句中使用。
其他回答
WHERE用于对SQL返回的集合进行限制;它使用SQL内置的集合操作和索引,因此是过滤结果集的最快方式。尽可能使用WHERE。
have对于某些聚合过滤器是必要的。它在sql检索、组装和排序结果之后过滤查询。因此,它比WHERE慢得多,应该避免,除非在需要它的情况下。
SQL Server将允许您使用HAVING,即使WHERE更快。不要这样做。
在聚合查询中(使用聚合函数的任何查询),Where子句中的谓词在生成聚合中间结果集之前求值,
Having子句中的谓词在聚合结果集生成后应用于聚合结果集。这就是为什么聚合值的谓词条件必须放在Having子句中,而不是放在Where子句中,以及为什么可以在Having子句中使用Select子句中定义的别名,而不能在Where子句中使用。
一种理解方法是,having子句是where子句的附加过滤器。
WHERE子句用于从结果中过滤记录。筛选器发生在任何分组之前。HAVING子句用于从组中筛选值
对我来说,第一个区别是:如果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