HAVING用法詳解


 

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 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 子句的輸出。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM