SQL Server舍入问题寻找解释

时间:2010-01-12 13:48:54

标签: sql sql-server stored-procedures rounding

我已经解决了这个问题,但我只是想知道为什么它的工作方式如此。我有一个临时表我正在选择,我希望显示一个名称,与此名称匹配的记录数,以及该记录总名称的百分比。这就是我最初的方式:

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

有人可以解释发生了什么,我想更好地理解这一点。谢谢!

乔恩

1 个答案:

答案 0 :(得分: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