我有一个ID,Value等结果的查询。我想要的是按照其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
我想出的是,为了这个目的,在结果和它自身之间使用内连接。但对于大量数据,这显然是一个低性能问题。
还有其他选择吗?
答案 0 :(得分:4)
在2012版中,您可以使用:
SELECT
id,
Value,
AccValue = SUM(Value) OVER (ORDER BY ID
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW)
FROM
@TempTable ;
对于以前版本的SQL-Server,请参阅我在这个类似问题中的回答:Recursive SQL- How can I get this table with a running total?,带有游标解决方案。
更好的是,请点击@Aaron Bertrand上的精彩文章链接,该文章详细测试了各种计算累计总数的方法: Best approaches for running totals – updated for SQL Server 2012
答案 1 :(得分: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 FIDDLE 强>
答案 2 :(得分: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