我必须用错误的方式搜索,或者我有一个愚蠢的时刻.
声明HAVING
和声明之间的区别WHERE
是SQL SELECT
什么?
编辑:我已经将史蒂文的答案标记为正确答案,因为它包含链接上的关键信息:
何时
GROUP BY
不使用,HAVING
表现得像一个WHERE
条款
我见过的WHERE
情况没有GROUP BY
,也是我的困惑开始的地方.当然,在您知道这一点之前,您无法在问题中指定它.
非常感谢所有非常有启发性的答案.
HAVING:用于在聚合发生后检查条件.
WHERE:用于在聚合发生之前检查条件.
这段代码:
select City, CNT=Count(1) From Address Where State = 'MA' Group By City
为您提供MA中所有城市的表格以及每个城市的地址数量.
这段代码:
select City, CNT=Count(1) From Address Where State = 'MA' Group By City Having Count(1)>5
为您提供MA的城市表格,其中包含超过5个地址和每个城市的地址数量.
HAVING指定SELECT语句中使用的组或聚合函数的搜索条件.
资源
对我来说最重要的一点是:如果HAVING
从SQL语言中删除,那么生活会像以前一样或多或少地继续下去.当然,少数查询需要使用派生表,CTE等进行重写,但结果可能更容易理解和维护.也许供应商的优化程序代码需要重写才能解决这个问题,这也是行业内部改进的机会.
现在考虑WHERE
从语言中删除一下.这一次,现有的大多数查询都需要在没有明显替代构造的情况下进行重写.编码器必须具有创造性,例如内连接到已知包含恰好一行的表(例如DUAL
在Oracle中),使用该ON
子句来模拟先前WHERE
子句.这样的结构将是人为的; 很明显,语言中缺少某些内容,因此情况会更糟.
TL; DR我们HAVING
明天可能输了,事情不会更糟,可能更好,但同样不能说WHERE
.
从这里的答案来看,似乎很多人都没有意识到一个HAVING
条款可以在没有条款的情况下使用GROUP BY
.在这种情况下,该HAVING
子句将应用于整个表表达式,并且只需要在SELECT
子句中出现常量.通常,该HAVING
条款将涉及聚合.
这比听起来更有用.例如,请考虑此查询以测试该name
列是否对于以下所有值都是唯一的T
:
SELECT 1 AS result FROM T HAVING COUNT( DISTINCT name ) = COUNT( name );
只有两种可能的结果:如果HAVING
子句为true,则结果为包含该值的单行1
,否则结果将为空集.
HAVING子句已添加到SQL,因为WHERE关键字不能与聚合函数一起使用.
查看此w3schools链接以获取更多信息
句法:
SELECT column_name, aggregate_function(column_name) FROM table_name WHERE column_name operator value GROUP BY column_name HAVING aggregate_function(column_name) operator value
像这样的查询:
SELECT column_name, COUNT( column_name ) AS column_name_tally FROM table_name WHERE column_name < 3 GROUP BY column_name HAVING COUNT( column_name ) >= 3;
...可以使用派生表(并省略HAVING
)重写,如下所示:
SELECT column_name, column_name_tally FROM ( SELECT column_name, COUNT(column_name) AS column_name_tally FROM table_name WHERE column_name < 3 GROUP BY column_name ) pointless_range_variable_required_here WHERE column_name_tally >= 3;
两者之间的区别在于与GROUP BY子句的关系:
GROUP BY之前的地方; SQL在对记录进行分组之前评估WHERE子句.
HADING来自GROUP BY; SQL在对记录进行分组后评估HAVING.
参考
SQLite SELECT语句语法/铁路图
Informix SELECT语句语法/铁路图
HAVING
当您使用聚合时使用GROUP BY
.
SELECT edc_country, COUNT(*) FROM Ed_Centers GROUP BY edc_country HAVING COUNT(*) > 1 ORDER BY edc_country;
WHERE适用于SQL返回的集合的限制; 它使用SQL的内置集合oeprations和索引,因此是过滤结果集的最快方法.始终尽可能使用WHERE.
某些聚合过滤器需要HAVING.它在sql检索,汇编和排序结果后过滤查询.因此,它比WHERE慢很多,应该避免,除非在那些需要它的情况下.
即使WHERE更快,SQL Server也可以让你使用HAVING.不要这样做.
WHERE子句不适用于聚合函数
意味着:你不应该使用这样的奖励:表名
SELECT name FROM bonus GROUP BY name WHERE sum(salary) > 200
HERE而不是使用WHERE子句,你必须使用HAVING ..
不使用GROUP BY子句,HAVING子句只作为WHERE子句
SELECT name FROM bonus GROUP BY name HAVING sum(salary) > 200