我必须以错误的方式进行谷歌搜索,否则我的时间很蠢。
什么之间的区别HAVING
,并WHERE
在SQL SELECT
声明中?
编辑:我已经标记了史蒂文的答案是正确的答案,因为它包含链接上信息的关键点:
当
GROUP BY
不使用时,HAVING
就像一个WHERE
条款
我所见过的WHERE
情况并没有发生,GROUP BY
而这正是我开始困惑的地方。当然,除非您知道这一点,否则无法在问题中指定它。
我必须以错误的方式进行谷歌搜索,否则我的时间很蠢。
什么之间的区别HAVING
,并WHERE
在SQL SELECT
声明中?
编辑:我已经标记了史蒂文的答案是正确的答案,因为它包含链接上信息的关键点:
当
GROUP BY
不使用时,HAVING
就像一个WHERE
条款
我所见过的WHERE
情况并没有发生,GROUP BY
而这正是我开始困惑的地方。当然,除非您知道这一点,否则无法在问题中指定它。
Answers:
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个以上的地址以及每个城市的地址数。
对我来说,第一大区别是:如果HAVING
从SQL语言中删除,那么生活将像以前一样或多或少地持续下去。当然,少数派查询将需要使用派生表,CTE等进行重写,但是这样可以使它们更易于理解和维护。也许需要重写供应商的优化器代码以解决此问题,这也是行业内改进的机会。
现在考虑一下WHERE
从该语言中删除。这次,将需要重写现有的大多数查询,而没有明显的替代结构。编码人员必须具有创造力,例如,DUAL
使用该ON
子句模拟上一个子句,对已知包含正好一行的表进行内部联接(例如在Oracle中)WHERE
。这种结构是人为设计的;很明显,该语言中缺少某些内容,因此情况将变得更糟。
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
子句为true,则结果为包含值的单行1
,否则结果为空集。
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
不明白这一点:之所以添加它,是因为没有将派生表添加到该语言中,并且直到它们成为SQL之前,它们之间的关系还不完整,并且不可避免地HAVING
变得多余。
两者之间的区别在于与GROUP BY子句的关系:
WHERE在GROUP BY之前;SQL在对记录进行分组之前会先评估WHERE子句。
HAVING在GROUP BY之后;SQL对记录进行分组后评估HAVING。
参考资料
SELECT 1 AS result FROM T HAVING...
-在您的图中无法HAVING
通过GROUP BY
而无法访问,但是我完全有效和有用的查询没有GROUP BY
。次要点:您无法选择在SELECT
子句中包含文字值。
WHERE->HAVING
部分感兴趣,因此我认为值得密切注意细节。如果您认为我的答案有误,请对其进行编辑或在评论中提出建议的更正。
应用WHERE作为对SQL返回的集合的限制;它使用SQL的内置集合运算和索引,因此是筛选结果集的最快方法。尽可能始终使用WHERE。
对于某些聚合过滤器,必须具有HAVING。它在sql检索,组合和排序结果之后过滤查询。因此,它比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
不使用when时,WHERE
and HAVING
子句实质上是等效的。
但是,何时GROUP BY
使用:
WHERE
子句用于从结果中过滤记录。过滤在进行任何分组之前进行。HAVING
子句用于从组中过滤值(即,在执行聚合到组后检查条件)。来自这里的资源
一种考虑方式是,having子句是where子句的附加过滤器。
使用WHERE子句从结果中过滤记录。过滤在进行任何分组之前发生。甲HAVING子句用于过滤器的值从一组
在进行项目时,这也是我的问题。如上所述,HAVING检查已找到的查询结果的条件。但是WHERE用于在查询运行时检查条件。
让我举一个例子来说明这一点。假设您有一个这样的数据库表。
usertable {int用户名,日期日期字段,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
现在,我们想要得到的userid
S和sum(dailyincome)
其sum(dailyincome)>100
如果我们写:
从用户表中选择userid,sum(dailyincome),sum(dailyincome)> 100 GROUP BY userid
这将是一个错误。正确的查询将是:
从用户表GROUP BY中选择用户ID,总和(每日收入)用户总和(每日收入)> 100
HAVING
是后聚合过滤器,而是WHERE
前聚合过滤器。