SQL中的HAVING和WHERE有什么区别?

SQL SELECT语句中,HAVINGWHERE之间有什么区别?

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

GROUP BY未被使用时,HAVING的行为类似WHERE子句

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

314934 次浏览

当你使用诸如GROUP BY这样的聚合时,会使用HAVING

SELECT edc_country, COUNT(*)
FROM Ed_Centers
GROUP BY edc_country
HAVING COUNT(*) > 1
ORDER BY edc_country;

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;

HAVING指定a的搜索条件

. group或SELECT语句中使用的聚合函数

Source .

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

在这里

SQL标准要求HAVING 中的列必须只引用 中使用的GROUP BY子句或列 聚合函数< / p >

而不是应用于数据库行的WHERE子句

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个地址的城市的表格,以及每个城市的地址数量。

WHERE用于对SQL返回的集合进行限制;它使用SQL内置的集合操作和索引,因此是过滤结果集的最快方式。尽可能使用WHERE。

have对于某些聚合过滤器是必要的。它在sql检索、组装和排序结果之后过滤查询。因此,它比WHERE慢得多,应该避免,除非在需要它的情况下。

SQL Server将允许您使用HAVING,即使WHERE更快。不要这样做。

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

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

我有一个问题,并发现了WHEREHAVING之间的另一个区别。它对索引列的作用不同。

WHERE my_indexed_row = 123将显示行,并自动对其他索引行执行“ORDER ASC”。

HAVING my_indexed_row = 123显示从最老的“插入”行到最新的行,没有排序。

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

现在考虑一下从语言中删除WHERE。这一次,现有查询的多数将需要在没有明显的替代构造的情况下重写。编码器必须有创造性,例如,使用ON子句来模拟前面的WHERE子句,内部连接到已知只包含一行的表(例如Oracle中的DUAL)。这样的结构是做作的;很明显,语言中缺少了一些东西,结果情况会更糟。

我们可能明天失去HAVING,情况不会更糟,可能会更好,但WHERE却不是这样。


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

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

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

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

在做项目的时候,这也是我的问题。如上所述,检查已经找到的查询结果的条件。但是在哪里用于在查询运行时检查条件。

让我举个例子来说明这一点。假设您有一个这样的数据库表。

用户表{int用户id,日期日期字段,int每日收入}

假设,表中有以下行:

1, 2011-05-20, 100

1, 2011-05-21, 50

1, 2011-05-30, 10

2, 2011-05-30, 10

2, 2011-05-20, 20

现在,我们想要得到__abc0和sum(dailyincome),它们的sum(dailyincome)>100

如果我们这样写:

SELECT用户id, sum(dailyincome) FROM usertable WHERE sum(dailyincome)>100 GROUP BY userid

这将是一个错误。正确的查询应该是:

SELECT userid, sum(dailyincome) FROM usertable GROUP BY userid HAVING 总和(dailyincome) > 100 < / p >

两者之间的区别在于与GROUP BY子句的关系:

  • WHERE在GROUP BY之前;SQL在对记录进行分组之前计算WHERE子句。

  • HAVING继GROUP BY之后;SQL在对记录进行分组后计算HAVING。

select语句图 .

参考文献

WHERE子句用于比较基表中的值,而HAVING子句可用于过滤查询结果集中的聚合函数的结果 点击在这里 !< / p >

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

当不使用GROUP BY时,WHEREHAVING子句本质上是等价的。

然而,当使用GROUP BY时:

  • WHERE子句用于从结果中过滤记录。的 在进行任何分组之前进行过滤
  • HAVING子句用于从组(即到)中过滤值
  • .执行分组聚合后检查条件)

Resource from 这里 . sh . sh

一种理解方法是,having子句是where子句的附加过滤器。

在哪里子句用于过滤结果中的记录。筛选器发生在任何分组之前。子句用于从组中筛选值

区别b/w WHEREHAVING子句:

WHEREHAVING子句的主要区别是,WHERE用于行操作,而HAVING用于列操作。

为什么我们需要HAVING子句?

我们知道,聚合函数只能在列上执行,所以不能在WHERE子句中使用聚合函数。因此,我们在HAVING子句中使用聚合函数。

当GROUP BY不使用时,WHERE和HAVING子句本质上是等价的。

然而,当使用GROUP BY时:

  • WHERE子句用于从结果中过滤记录。的 在进行任何分组之前进行过滤
  • HAVING子句为 用于从一个组中过滤值(即,检查后的条件
  • . . .