HAVING
和WHERE
在SQL SELECT
语句中有什么区别?
编辑:我已将Steven的答案标记为正确答案,因为它包含了该链接上的关键信息:
当未使用
GROUP BY
时,HAVING
的行为类似于WHERE
子句。
我曾经看到WHERE
的情况没有使用GROUP BY
,这就是我的困惑所在。当然,除非你知道这一点,否则你无法在问题中指定它。
HAVING
和WHERE
在SQL SELECT
语句中有什么区别?
编辑:我已将Steven的答案标记为正确答案,因为它包含了该链接上的关键信息:
当未使用
GROUP BY
时,HAVING
的行为类似于WHERE
子句。
我曾经看到WHERE
的情况没有使用GROUP BY
,这就是我的困惑所在。当然,除非你知道这一点,否则你无法在问题中指定它。
HAVING:用于在聚合完成后检查条件。
WHERE:用于在聚合之前检查条件。
这段代码:
select City, CNT=Count(1)
From Address
Where State = 'MA'
Group By City
提供了一个包含马萨诸塞州所有城市及每个城市地址数量的表格。
此代码:
select City, CNT=Count(1)
From Address
Where State = 'MA'
Group By City
Having Count(1)>5
提供了一个包含马萨诸塞州拥有五个以上地址的城市及每个城市地址数量的表格。
HAVING
,那么生活还会继续,或多或少地保持原样。当然,少数查询需要使用派生表、CTE等来重写,但由于这个原因,它们可能更容易理解和维护。也许供应商的优化器代码需要重新编写以解决这个问题,这是行业改进的机会。WHERE
。这时,大多数现有的查询都需要重写,而没有明显的替代构造。程序员必须变得有创意,例如,使用内部连接到一个已知包含恰好一行的表(例如Oracle中的DUAL
),使用ON
子句模拟先前的WHERE
子句。这种构造是牵强附会的;很明显语言中缺少了某些东西,情况会更糟。HAVING
,事情不会更糟,可能会更好,但不能这样说WHERE
。
HAVING
子句可以在没有GROUP BY
子句的情况下使用。在这种情况下,HAVING
子句应用于整个表达式,并要求SELECT
子句中只出现常量。通常,HAVING
子句涉及聚合。T
中所有值的name
列是否唯一:SELECT 1 AS result
FROM T
HAVING COUNT( DISTINCT name ) = COUNT( name );
只有两种可能的结果:如果HAVING
子句为真,则结果将是包含值1
的单行,否则结果将为空集。
两者的区别在于它们与GROUP BY子句的关系:
WHERE在GROUP BY之前,SQL在对记录进行分组前评估WHERE子句。
HAVING在GROUP BY之后,SQL在对记录进行分组后评估HAVING子句。
参考资料
GROUP BY
,那么就没有隐式分组。但我仍然有点困惑,不知道这与您的图表缺少有效路径有何关系。 - onedaywhenCREATE TABLE T (c CHAR(1)); INSERT INTO T VALUES ('a'),('a'); SELECT 'true' FROM T HAVING COUNT (c) = 2;
应该是单行单列结果,显示 true
,因为搜索条件没有删除任何行,即未应用隐式分组(如果有分组,则 COUNT(c)
将为 1,搜索条件将失败,即零行结果)。 - onedaywhen由于 WHERE 关键字不能与聚合函数一起使用,因此 HAVING 子句被添加到 SQL 中。
查看此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;
HAVING
是因为语言中没有派生表格而被添加的,直到它们被加入后SQL才具备关系完备性,一旦它们被不可避免地加入,HAVING
就变得多余了。 - onedaywhenHAVING
是在使用诸如GROUP BY
的聚合时使用的。
SELECT edc_country, COUNT(*)
FROM Ed_Centers
GROUP BY edc_country
HAVING COUNT(*) > 1
ORDER BY edc_country;
WHERE子句不能用于聚合函数
意思是:您不应该像这样使用
附加信息:表名
SELECT name
FROM bonus
GROUP BY name
WHERE sum(salary) > 200
在使用HAVING子句的情况下,不需要使用WHERE子句。如果没有使用GROUP BY子句,则HAVING子句就像WHERE子句一样起作用。
SELECT name
FROM bonus
GROUP BY name
HAVING sum(salary) > 200
WHERE在SQL中用于限制返回的数据集,它使用SQL内置的集合操作和索引,因此是过滤结果集最快的方法。尽可能使用WHERE。
HAVING对于一些聚合过滤是必需的。它在SQL检索、组装和排序结果后再进行过滤。因此,它比WHERE慢得多,除非必须使用HAVING,在其他情况下应该避免使用。
即使使用WHERE会更快,SQL Server也允许您使用HAVING。不要这样做。
WHERE
和HAVING
子句的区别:
WHERE
用于行操作,而HAVING
用于列操作。
为什么我们需要HAVING
子句?
正如我们所知,聚合函数只能在列上执行,因此我们无法在WHERE
子句中使用聚合函数。因此,我们使用HAVING
子句来使用聚合函数。
可以这样理解:having子句是where子句的一个额外条件过滤器。
WHERE子句用于在结果集中筛选记录。过滤发生在任何分组之前。而HAVING子句用于从分组中筛选值。
HAVING
是一个聚合后的过滤器,而WHERE
是一个聚合前的过滤器。 - Nick ChammasHAVING
而不带GROUP BY
作为WHERE
的替代方法并不被普遍接受。 - Saeed Ahadian