2010-01-12 56 views
1

我已經解決了這個問題,但我只是想知道爲什麼這個工作的方式。我有一個臨時表,我正在從中進行選擇,並且正在尋找顯示一個名稱,與此名稱匹配的記錄數以及該記錄名稱的百分比。這是這樣的我本來它:SQL Server舍入問題尋找解釋

SELECT name, number, 
CASE WHEN number = 0 THEN 0 ELSE 
convert(Numeric(10,2), number/CONVERT(decimal(5,2),SUM(number)) * 100) 
END as "Percentage of Total" 
FROM #names 
group by name, number 

我收到的結果是:

name      number  Percentage of Total 
------------------------- ----------- --------------------------------------- 
Test 1      0   0.00 
Test 2      22   100.00 
Test 3      28   100.00 

當我更改查詢到這一點,結果是正確的:

declare @total decimal(5,2) 

    select @total = SUM(number) FROM #names 

    SELECT name, number, convert(Numeric(10,2), number/ @total * 100) as "Percentage of Total" 
    FROM #names 
    group by name, number 

正確結果:

name      number  Percentage of Total 
------------------------- ----------- --------------------------------------- 
Test 1      22   44.00 
Test 2      0   0.00 
Test 3      28   56.00 

有人可以解釋發生了什麼,我想更好地理解這一點。謝謝!

Jon

回答

1

您首先按編號查詢組。

由於您沒有重複的號碼,因此number/SUM(number)相當於1/COUNT(數字爲0時除外)。

你的第二個查詢不按數字分組,它計算總數。

使用這個代替:

SELECT name, number * 100.0/SUM(number) OVER() 
FROM #names 

OVER子句中使用,SUM成爲解析函數,而不是總之一。

它不縮水幾條記錄到一個:相反,它與每個記錄一起返回的總價值:

-- This is an aggregate function. It shrinks all records into one record and returns the total sum 

WITH q (name, number) AS 
     (
     SELECT 'test1', 0 
     UNION ALL 
     SELECT 'test2', 22 
     UNION ALL 
     SELECT 'test3', 28 
     ) 
SELECT SUM(number) 
FROM q 

-- 
50 

-- This is an analytical function. It calcuates the total sum as well but does not shrink the records. 

WITH q (name, number) AS 
     (
     SELECT 'test1', 0 
     UNION ALL 
     SELECT 'test2', 22 
     UNION ALL 
     SELECT 'test3', 28 
     ) 
SELECT SUM(number) OVER() 
FROM q 

-- 
50 
50 
50 
+0

哇感謝您的快速反應和巨大的答案!你能解釋一下OVER()在這個查詢中做什麼?它完美的工作,我只是想了解發生了什麼。 – Jon 2010-01-12 13:59:57