HAVING和WHERE有什么区别?
我必须用错误的方式使用Googlesearch,或者我在时间上有一个愚蠢的时刻。
在SQL SELECT
语句中, HAVING
和WHERE
什么区别?
编辑:我已经标记了史蒂芬的答案是正确的,因为它包含链接上的关键信息位:
当不使用
GROUP BY
,HAVING
行为像一个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中,我们有很多的聚合函数。 例子
- 计数()
- 和()
- AVG()
- MIN()
- 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 BY
, WHERE
和HAVING
子句基本上是等价的。
但是,使用GROUP BY
时:
-
WHERE
子句用于过滤结果中的logging。 过滤发生在任何分组之前。 -
HAVING
子句用于过滤来自组的值(即,在聚合成组之后检查条件)。
这里的资源
差异b / w WHERE
和HAVING
子句:
WHERE
和HAVING
子句的主要区别在于, WHERE
用于行操作, HAVING
用于列操作。
为什么我们需要HAVING
子句?
正如我们所知,集合函数只能在列上执行,所以我们不能在WHERE
子句中使用集合函数。 因此,我们在HAVING
子句中使用聚合函数。
我遇到了一个问题,发现了WHERE
和HAVING
之间的另一个区别。 它在索引列上的行为不一样。
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)>100
的userid
和sum(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”的主题是一个组。 我对吗?