280

HAVING声明中和WHERE有什么区别SQL SELECT

编辑:我已将史蒂文的答案标记为正确答案,因为它包含链接上的关键信息:

GROUP BY不使用时,行为HAVING类似于WHERE子句

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

4

18 回答 18

397

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

于 2008-11-13T16:53:37.983 回答
100

HAVING 为 SELECT 语句中使用的组或聚合函数指定搜索条件。

来源

于 2008-11-13T16:48:26.233 回答
28

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

现在考虑一下WHERE从语言中删除。这一次,存在的大多数查询都需要在没有明显替代构造的情况下重写。编码人员将不得不使用该子句来模拟先前的子句,例如对已知仅包含一行的表进行内部连接(例如DUAL在 Oracle 中)。这样的结构是人为的;很明显,语言中缺少某些东西,结果情况会更糟。ONWHERE

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子句为真,则结果为包含 value 的单行1,否则结果将为空集。

于 2011-11-28T10:15:32.270 回答
22

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;
于 2008-11-13T16:47:53.253 回答
22

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

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

  • HAVING 在 GROUP BY 之后;SQL 在对记录进行分组后评估 HAVING。

选择语句图

参考

于 2012-08-29T00:57:57.793 回答
12

HAVING当您使用聚合(例如GROUP BY.

SELECT edc_country, COUNT(*)
FROM Ed_Centers
GROUP BY edc_country
HAVING COUNT(*) > 1
ORDER BY edc_country;
于 2008-11-13T16:47:06.703 回答
8

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

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

即使在 WHERE 更快的情况下,SQL Server 也会让您轻松使用 HAVING。不要这样做。

于 2008-11-13T16:53:49.903 回答
7

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  
于 2016-03-17T12:49:58.230 回答
4

区别黑白WHEREHAVING子句:

WHEREandHAVING子句的主要区别在于,WHERE用于行操作和HAVING用于列操作。

为什么我们需要HAVING从句?

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

于 2016-12-31T05:17:17.117 回答
2

一种思考方式是,have 子句是 where 子句的附加过滤器。

WHERE子句用于过滤结果中的记录。过滤器发生在进行任何分组之前。HAVING子句用于过滤组中的值

于 2016-12-31T05:06:37.540 回答
1

在聚合查询中,(使用聚合函数的任何查询)where 子句中的谓词在生成聚合中间结果集之前进行评估,

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

于 2008-11-13T16:56:27.463 回答
1

WHERE我遇到了一个问题,发现和之间的另一个区别HAVING。它对索引列的作用不同。

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

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

于 2011-03-09T16:50:57.423 回答
1

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

但是,何时GROUP BY使用:

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

来自这里的资源

于 2016-10-02T20:09:56.680 回答
0

这里

SQL 标准要求 HAVING 必须仅引用 GROUP BY 子句中的列或聚合函数中使用的列

与应用于数据库行的 WHERE 子句相反

于 2008-11-13T16:50:14.763 回答
0

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

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

usertable{ int userid, date datefield, int dailyincome }

假设,以下行在表中:

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

现在,我们想要得到userids 和sum(dailyincome)whosum(dailyincome)>100

如果我们写:

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

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

SELECT userid, sum(dailyincome) FROM usertable GROUP BY userid HAVING sum(dailyincome)>100

于 2012-06-06T10:26:58.647 回答
0

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

于 2013-01-29T10:33:42.847 回答
0

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

但是,当使用 GROUP BY 时:

  • WHERE 子句用于从结果中过滤记录。过滤发生在进行任何分组之前。
  • HAVING 子句用于过滤组中的值(即,在执行聚合到组后检查条件)。
于 2020-06-23T14:47:11.527 回答
-1

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

于 2008-11-13T16:49:08.743 回答