如何在SQL Server計算資料行和平均值

來源:互聯網
上載者:User

嚴格來說,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.CustomerID = Sales.Customer.CustomerID     INNER JOIN Sales.SalesOrderDetail     ON Sales.SalesOrderDetail.SalesOrderID = Sales.SalesOrderHeader.SalesOrderIDGROUP BY     Sales.Customer.CustomerID,     Sales.SalesOrderHeader.SalesOrderIDHAVING 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.SalesOrderID = Sales.SalesOrderHeader.SalesOrderIDGROUP BY     Sales.SalesOrderHeader.SalesOrderID

列表B:

Msg 130, Level 15, State 1, Line 1Cannot perform an aggregate function on an expression containing an aggregate or a subquery.

錯誤資訊:

你可以將平均值的計算過程進行分解來解決這個問題。你可以將第一部分(SUM)編寫成一個表值UDF,如列表C所示。你可以根據列表D中的Function Compute平均值。列表E說明你如何能夠進行組合。

USE [AdventureWorks]GO/****** Object: UserDefinedFunction [dbo].[SalesTotals_fnt]   Script Date: 12/09/2006 11:32:54 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE FUNCTION [dbo].[SalesTotals_fnt]()RETURNS TABLEAS 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 moneyASBEGIN     -- 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 @ResultEND

列表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'     ENDFROM dbo.SalesTotals_fnt()

列表E:

現在你知道了如何根據一個子表使用Having子句來測試合計值。當你需要在一個查詢中使用兩個不同的合計函數時,最好是把它們分解成單獨的函數,然後再進行組合(如前一個例子所說明的)。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.