SQLHAVING⽤法详解
HAVING ⼦句对 GROUP BY ⼦句设置条件的⽅式与 WHERE 和 SELECT 的交互⽅式类似。WHERE 搜索条件在进⾏分组操作之前应⽤;⽽ HAVING 搜索条件在进⾏分组操作之后应⽤。HAVING 语法与 WHERE 语法类似,但 HAVING 可以包含聚合函数。HAVING ⼦句可以引⽤选择列表中显⽰的任意项。
下⾯的⽰例按产品 ID 对 SalesOrderDetail 进⾏了分组,并且只包含那些订单合计⼤于 $1,000,000 且其平均订单数量⼩于 3 的产品组。
USE AdventureWorks;
GO
SELECT ProductID, AVG(OrderQty) AS AverageQuantity, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $1000000.00
AND AVG(OrderQty) < 3 ;
GO
请注意,如果 HAVING 中包含多个条件,那么这些条件将通过 AND、OR 或 NOT 组合在⼀起。
若要查看总销量⼤于 $2,000,000 的产品,请使⽤下⾯的查询:
USE AdventureWorks;
GO
SELECT ProductID, Total = SUM(LineTotal)
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING SUM(LineTotal) > $2000000.00 ;
GO
下⾯是结果集:
ProductID  Total
----------- ----------------------
781        3864606.54937208
969        2010943.97244001
793        2897478.01200001
784        3699803.72383008
780        3880441.60780208
976        2079038.42948
795        2268057.09000002
783        4548164.01783709
779        4170215.3849281
782        5032968.13026809
794        2679200.01336002
753        2006264.4236
(12 row(s) affected)
若要确保对每种产品的计算中⾄少包含 1500 项,请使⽤ HAVING COUNT(*) > 1500 消除返回的销售总数⼩于 1500 项的产品。该查询类似于下⾯的⽰例:
USE AdventureWorks;
GO
SELECT ProductID, SUM(LineTotal) AS Total
FROM Sales.SalesOrderDetail
GROUP BY ProductID
HAVING COUNT(*) > 1500 ;
GO
理解应⽤ WHERE、GROUP BY 和 HAVING ⼦句的正确顺序对编写⾼效的查询代码会有所帮助:
WHERE ⼦句⽤来筛选 FROM ⼦句中指定的操作所产⽣的⾏。
GROUP BY ⼦句⽤来分组 WHERE ⼦句的输出。
HAVING ⼦句⽤来从分组的结果中筛选⾏。
对于可以在分组操作之前或之后应⽤的任何搜索条件,在 WHERE ⼦句中指定它们会更有效。这样可以减少必须分组的⾏数。应当在HAVING ⼦句中指定的搜索条件只是那些必须在执⾏分组操作之后应⽤的搜索条件。
Microsoft SQL Server 2005 查询优化器可以处理这些条件中的⼤多数条件。如果查询优化器确定 HAVING 搜索条件可以在分组操作之前应⽤,那么它就会在分组之前应⽤。查询优化器可能⽆法识别所有可以在分组操作之前应⽤的 HAVING 搜索条件。建议将所有这些搜索条件放在 WHERE ⼦句中,⽽不是 HAVING ⼦句中。
下⾯的⽰例显⽰了带有聚合函数的 HAVING ⼦句。它按产品 ID 分组 SalesOrderDetail 表中的⾏,并消除其平均订单数量⼩于/等于 5 的产品。
USE AdventureWorks;
GO
SELECT ProductID
FROM Sales.SalesOrderDetail
group by的用法及原理详解GROUP BY ProductID
HAVING AVG(OrderQty) > 5
ORDER BY ProductID ;
GO
下⾯的⽰例显⽰了不带聚合函数的 HAVING ⼦句。它按名称分组 ProductModel 表中的⾏,并消除那些不以 Mountain 开头的名称。
USE AdventureWorks;
GO
SELECT pm.Name, AVG(ListPrice) AS 'Average List Price'
FROM Production.Product AS p
JOIN Production.ProductModel AS pm
ON p.ProductModelID = pm.ProductModelID
GROUP BY pm.Name
HAVING pm.Name LIKE 'Mountain%'
ORDER BY pm.Name ;
GO
请注意,ORDER BY ⼦句可⽤于排序 GROUP BY ⼦句的输出。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。