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

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

編輯:關於MYSQL數據庫

     嚴格來說,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