燈火互聯
管理員
管理員
  • 注冊日期2011-07-27
  • 發帖數41646
  • QQ
  • 火幣40950枚
  • 粉絲1085
  • 關注100
  • 終身成就獎
  • 最愛沙發
  • 忠實會員
  • 灌水天才獎
  • 貼圖大師獎
  • 原創先鋒獎
  • 特殊貢獻獎
  • 宣傳大使獎
  • 優秀斑竹獎
  • 社區明星
閱讀:11571回復:1

[SQL Server]在SQL Server數據庫中求計算列和平均值

樓主#
更多 發布于:2014-09-23 13:07
嚴格來說,Having并不需要一個子表,但沒有子表的Having并沒有實際意義。如果你只需要一個表,那么你可以用Where子句達到一切目的。為進行實踐,Having預先假定至少兩個表和一個基于第二個表的合計函數。
 
下面是一個簡單的例子:你想要訂單總數超過25000美元的客戶清單。你需要適當連接的三個表:Customer、SalesOrderHeader和SalesOrderDetail。然后,你求Detail的和,并將總數與25000美元進行比較。查看列表A。
 
查看列表A中的代碼時,有一件事情并不明顯,即LineTotal列被計算。你可以像求實際的列的和一樣求出已計算列的和。但是,你不能在同一個操作中執行兩個不同層次的合計函數。
 SELECT    
Sales.Customer.CustomerID,    
Sales.SalesOrderHeader.SalesOrderID,    
SUM(Sales.SalesOrderDetail.LineTotal)
AS SubTotalFROM    
Sales.Customer    
INNER JOIN Sales.SalesOrderHeader    
ON Sales.SalesOrderHeader.Customer
ID = Sales.Customer.CustomerID    
INNER JOIN Sales.SalesOrderDetail    
ON Sales.SalesOrderDetail.SalesOrder
ID = Sales.SalesOrderHeader.SalesOrderIDGROUP BY    
Sales.Customer.CustomerID,    
Sales.SalesOrderHeader.SalesOrder
IDHAVING SUM(LineTotal) > 25000.00ORDER BY    
Sales.Customer.CustomerID,    
SalesOrderID ;
列表A:
 
假設你希望知道所有客戶的平均銷售額。你可以使用列表B中的代碼,它返回如下錯誤信息:
 SELECT    
Sales.SalesOrderHeader.SalesOrderID,    
AVG(SUM(Sales.SalesOrderDetail.LineTotal))
AS AverageFROM    
Sales.SalesOrderHeader    
INNER JOIN Sales.SalesOrderDetail    
ON Sales.SalesOrderDetail.SalesOrder
ID = Sales.SalesOrderHeader.SalesOrder
IDGROUP BY    
Sales.SalesOrderHeader.SalesOrderID
列表B:
 Msg 130, Level 15, State 1, Line 1
Cannot perform an aggregate function on an expression
containing an aggregate or a subquery.
錯誤信息:
 
你可以將平均值的計算過程進行分解來解決這個問題。你可以將第一部分(SUM)編寫成一個表值UDF,如列表C所示。你可以根據列表D中的函數計算平均值。列表E說明你如何能夠進行組合。
 USE [AdventureWorks]
GO
/****** Object: UserDefinedFunction
[dbo].[SalesTotals_fnt]  
Script Date: 12/09/2006 11:32:54 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[SalesTotals_fnt]()
RETURNS TABLE
AS RETURN    
(SELECT SalesOrderID,
SUM(LineTotal)AS TotalSale    
FROM Sales.SalesOrderDetail    
GROUP BY Sales.SalesOrderDetail.SalesOrderID)
列表C:
 CREATE FUNCTION [dbo].[AverageSale_fns] (    
-- Add the parameters for the function here    
-- )RETURNS money
ASBEGIN    
-- Declare the return variable here    
DECLARE @Result money
-- Add the T-SQL statements to compute the return value here    
SET @Result =(SELECTAvg(TotalSale)AS AverageSale    
FROM dbo.SalesTotals_fnt())
-- Return the result of the function    
RETURN @Result
END
列表D:
 DECLARE @Avg moneySELECT @Avg = dbo.AverageSale_fns()
SELECT     *, @Avg as Average,    
TotalSale / @Avg as Ratio,     CASE        
WHEN TotalSale / @Avg > 1 THEN 'Above Average'      
WHEN TotalSale / @Avg < 1 THEN 'Below Average'        
ELSE 'Average'     END
FROM dbo.SalesTotals_fnt()
列表E:
 
現在你知道了如何根據一個子表使用Having子句來測試合計值。當你需要在一個查詢中使用兩個不同的合計函數時,最好是把它們分解成單獨的函數,然后再進行組合(如前一個例子所說明的)。

喜歡1 評分0

最新喜歡:

王獻文王獻文
王獻文
終身會員
終身會員
  • 注冊日期2015-01-12
  • 發帖數31
  • QQ2388572004
  • 火幣35枚
  • 粉絲0
  • 關注0
沙發#
發布于:2015-04-09 18:48
不錯

回復(0) 喜歡(0)     評分
游客

返回頂部
大乐透开奖结果走势图