HAVING和WHERE有什么区别?

我必须用错误的方式使用Googlesearch,或者我在时间上有一个愚蠢的时刻。

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

编辑:我已经标记了史蒂芬的答案是正确的,因为它包含链接上的关键信息位:

当不使用GROUP BYHAVING行为像一个WHERE子句

我所看到的WHERE情况并没有GROUP BY ,是我开始混淆的地方。 当然,直到你知道这个,你不能在问题中指定它。

非常感谢所有非常有启发性的答案。

HAVING指定在SELECT语句中使用的组或集合函数的search条件。

资源

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 

给你一个在5个以上的地址和每个城市的地址数量在MA的城市表。

对我来说,第一个区别是:如果将HAVING从SQL语言中删除,那么生活将会像以前一样或多或less地继续下去。 当然,less数查询需要使用派生表,CTE等来重写,但是由此可以更容易理解和维护。 为了解决这个问题,厂商的优化代码可能需要重写,这也是行业内需要改进的一个机会。

现在考虑从语言中删除WHERE 。 这一次, 大部分存在的查询都需要重写,而没有明显的替代结构。 编码器将不得不使用ON子句来模拟先前的WHERE子句,例如,内部连接到已知只包含一行的表(例如Oracle中的DUAL )。 这样的构造将会被devise出来。 语言中会缺less一些东西,情况就会变得更糟。

TL; DR明天我们可能会失去HAVING ,事情也不会更糟,可能会更好,但同样不能说WHERE


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

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

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

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

WHERE和HAVING子句之间的区别:

1. WHERE子句可以与 – Select,Insert和Update语句一起使用,其中HAVING子句只能与Select语句一起使用。

2. WHERE过滤聚合之前的行(GROUPING),其中as, HAVING过滤聚合后执行聚合。

3.集合函数不能在WHERE子句中使用 ,除非它在HAVING子句中包含的子查询中,而在Having子句中可以使用集合函数。

过滤组:

WHERE子句用于在聚合之前过滤行,其中HAVING子句用于在聚合之后过滤组

 Select City, SUM(Salary) as TotalSalary from tblEmployee Where Gender = 'Male' group by City Having City = 'London' 

在SQL Server中,我们有很多的聚合函数。 例子

  1. 计数()
  2. 和()
  3. AVG()
  4. MIN()
  5. MAX()

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在对logging进行分组之前先评估WHERE子句。

  • HAVING在GROUP BY之后出现; 在对logging进行分组后,SQL将对HAVING进行评估。

选择语句图

参考

  • SQLite SELECT语句语法/铁路图

  • Informix SELECT语句语法/铁路图

当您使用GROUP BY等聚合时,使用HAVING

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

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

HAVING对于一些集合filter是必需的。 它在sql检索,汇编和sorting结果后过滤查询。 因此,它比WHERE慢得多,应该避免,除非在那些需要它的情况下。

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

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 BYWHEREHAVING子句基本上是等价的。

但是,使用GROUP BY时:

  • WHERE子句用于过滤结果中的logging。 过滤发生在任何分组之前。
  • HAVING子句用于过滤来自组的值(即,在聚合成组之后检查条件)。

这里的资源

差异b / w WHEREHAVING子句:

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

为什么我们需要HAVING子句?

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

我遇到了一个问题,发现了WHEREHAVING之间的另一个区别。 它在索引列上的行为不一样。

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

HAVING my_indexed_row = 123显示从最旧的“插入”行到最新的一切,没有sorting。

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

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

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

有一种方法可以认为,having子句是where子句的附加filter。

WHERE子句用于从结果中过滤logging。 filter发生在任何分组之前。 HAVING子句用于过滤来自组的值

我使用HAVING来根据聚集函数的结果约束一个查询。 EGselect*在blahblahblah组由SOMETHING计数(SOMETHING)> 0

从这里 。

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

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

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

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

usertable {int用户标识符,datedate字段,诠释日常收入}

假设,下面的行在表中:

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

现在,我们要获得sum(dailyincome) sum(dailyincome)>100useridsum(dailyincome)

如果我们写:

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

可能只是“where”的主题是连续的,而“having”的主题是一个组。 我对吗?