4

我有一个查询结果,如 ID、值。我想要的是按它们的 id 顺序获取值,并计算另一列中的累积值。看看我的简化代码:

declare @TempTable Table
(
    ID int,
    Value int
)
insert into @TempTable values
(1, 10),
(2, -15),
(3, 12),
(4, 18),
(5, 5)

select t1.ID, t1.Value, SUM(t2.Value) AccValue from @TempTable t1
inner join @TempTable t2 on t1.ID >= t2.ID
group by t1.ID, t1.Value
order by t1.ID




Result:
ID  Value   AccValue
1   10      10
2   -15     -5
3   12      7
4   18      25
5   5       30

我想出的是为此目的在结果和自身之间使用内部连接。但是对于大量数据,这显然是一个低性能问题。

还有其他选择吗?

4

3 回答 3

5

在 2012 版本中,您可以使用:

SELECT
    id,
    Value,
    AccValue = SUM(Value) OVER (ORDER BY ID 
                                ROWS BETWEEN UNBOUNDED PRECEDING 
                                         AND CURRENT ROW)
FROM 
    @TempTable ;

对于 SQL-Server 的早期版本,请参阅我在这个类似问题中的回答:递归 SQL-如何获得这个表的运行总数?, 带有游标解决方案。

更好的是,请点击@Aaron Bertrand的精彩文章的链接,该文章对计算运行总计的各种方法进行了全面测试:运行总计的最佳方法 – 针对 SQL Server 2012 更新

于 2013-07-08T12:59:37.540 回答
2

您可以使用递归:

;WITH x AS
(
    SELECT 
        [ID],
        [Value],
        bal=[Value]
    FROM Table1
    WHERE [ID] = 1
    UNION ALL
    SELECT 
        y.[ID],
        y.[Value],
        x.bal+(y.[Value]) as bal
    FROM x INNER JOIN Table1 AS y
    ON y.[ID] = x.[ID] + 1
)
SELECT 
    [ID],
    [Value],
    AccValue= bal
FROM x
order by ID
OPTION (MAXRECURSION 10000);

SQL 小提琴

于 2013-07-08T13:56:05.873 回答
1

执行此操作的通用 SQL 方法是使用相关子查询(至少,我认为这是最干净的方法):

select t.*,
       (select sum(t2.value)
        from @TempTable t2
        where t2.ID <= t.ID
       ) AccValue
from @TempTable t

SQL Server 2012 具有累积求和功能:

select t.*,
       sum(t.value) over (order by t.id) as AccValue
from @TempTable t
于 2013-07-08T12:55:29.063 回答