WHERE和HAVING子句有什么区别?

目录

Where和Having有何不同?

WHERE子句

HAVING子句

结合两者:WHERE和HAVING


在本文中学习何时使用WHEREHAVING。两者都执行类似的功能,但用于不同的目的!

本文的所有示例都基于Microsoft SQL Server Management StudioAdventureWorks2012数据库。

WhereHaving有何不同?

使用更高级的SQL时,可能不清楚何时使用WHEREHAVING子句才是有意义的。

虽然看起来两个子句都做同样的事情,但它们以不同的方式做到的。事实上,它们的功能相互补充。

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

在我们继续之前,让我们回顾一下SQL语句的格式。它是

SELECT
FROM
WHERE
GROUP BY
HAVING

为了帮助保持正确,我喜欢从上到下考虑SQL语句的执行顺序。这意味着首先将WHERE子句应用于结果,然后根据GROUP BY汇总剩余的行。

WHERE子句

WHERE子句用于从结果中过滤行。例如

SELECT   COUNT(SalesOrderID)
FROM     Sales.SalesOrderDetail

返回121,317作为计数,而查询

SELECT   COUNT(SalesOrderID)
FROM     Sales.SalesOrderDetail
WHERE    UnitPrice > 200

返回48,159作为计数。这是因为WHERE子句从结果中过滤出UnitPrice小于或等于20073,158SalesOrderDetails

HAVING子句

HAVING子句用于过滤GROUP BY中的值。您可以使用它们来过滤掉分组,如下

SELECT   SalesOrderID,
         SUM(UnitPrice * OrderQty) AS TotalPrice
FROM     Sales.SalesOrderDetail
GROUP BY SalesOrderID
HAVING   SalesOrderID > 50000

但它们的真正力量在于它们能够根据聚合函数结果进行比较和过滤。例如,您可以选择总额超过10,000美元的所有订单

SELECT   SalesOrderID,
         SUM(UnitPrice * OrderQty) AS TotalPrice
FROM     Sales.SalesOrderDetail
GROUP BY SalesOrderID
HAVING   SUM(UnitPrice * OrderQty) > 10000

由于WHERE子句的可见性是一次一行,因此无法在所有SalesOrderID中评估SUM。在创建分组后评估HAVING子句。

结合两者:WHEREHAVING

SQL语句同时具有WHERE子句和HAVING子句时,请记住首先应用WHERE子句,然后将结果分组,最后根据HAVING子句过滤组。

在许多情况下,您可以将WHERE条件放在HAVING子句中,例如

SELECT   SalesOrderID,
         SUM(UnitPrice * OrderQty) AS TotalPrice
FROM     Sales.SalesOrderDetail
GROUP BY SalesOrderID
HAVING   SUM(UnitPrice * OrderQty) > 10000 
         AND SalesOrderID > 50000

Vs

SELECT   SalesOrderID,
         SUM(UnitPrice * OrderQty) AS TotalPrice
FROM     Sales.SalesOrderDetail
WHERE    SalesOrderID > 50000
GROUP BY SalesOrderID
HAVING   SUM(UnitPrice * OrderQty) > 10000

如果你可以从having子句中的where子句中添加条件那么为什么甚至担心WHERE?我可以使用此查询吗?

SELECT   SalesOrderID,
         SUM(UnitPrice * OrderQty) AS TotalPrice
FROM     Sales.SalesOrderDetail
GROUP BY SalesOrderID
HAVING   SUM(UnitPrice * OrderQty) > 10000 AND LineTotal > 10

实际上该查询会生成错误。LineTotal列不是按字段列表的组成部分,也不是总计的结果。

为了有效,having子句只能比较聚合函数的结果或组的列部分。

为了有效,必须将查询重写为

SELECT   SalesOrderID,
         SUM(UnitPrice * OrderQty) AS TotalPrice
FROM     Sales.SalesOrderDetail
WHERE    LineTotal > 100
GROUP BY SalesOrderID
HAVING   SUM(UnitPrice * OrderQty) > 10000

总结一下WHEREHAVING的区别:

  • WHERE用于在任何分组发生之前过滤记录。
  • HAVING用于在组成为组后过滤值。只有组中的列或表达式才能包含在HAVING子句的条件中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值