您当前的位置: 首页 > 

寒冰屋

暂无认证

  • 0浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

WHERE和HAVING子句有什么区别?

寒冰屋 发布时间:2019-09-12 21:30:39 ,浏览量:0

目录

Where和Having有何不同?

WHERE子句

HAVING子句

结合两者:WHERE和HAVING

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

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

Where和Having有何不同?

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

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

  • 使用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小于或等于200的73,158个SalesOrderDetails。

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子句。

结合两者:WHERE和HAVING

当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

总结一下WHERE和HAVING的区别:

  • WHERE用于在任何分组发生之前过滤记录。
  • HAVING用于在组成为组后过滤值。只有组中的列或表达式才能包含在HAVING子句的条件中。
关注
打赏
1665926880
查看更多评论
立即登录/注册

微信扫码登录

0.0655s