程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> 如何在SQL Server計算列和平均值

如何在SQL Server計算列和平均值

編輯:關於SqlServer

嚴格來說,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. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved