ID debit credit sum_debit
---------------------------------
1 150 0 150
2 100 0 250
3 0 50 200
4 0 100 100
5 50 0 150
我有这个表格,我的问题是如何获取sum_debit
列,这是前一行sum_debit
的总和,借记减去信用(sum_debit = sum_debit + debit - credit
)。
每个新行我输入借方但信用数据为零,或者输入信用值和借方为零。我如何获得sum_debit
?
答案 0 :(得分:4)
在SQL-Server 2012中,您可以使用新添加的ROWS
or RANGE
子句:
SELECT
ID, debit, credit,
sum_debit =
SUM(debit - credit)
OVER (ORDER BY ID
ROWS BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW
)
FROM
CreditData
ORDER BY
ID ;
中进行测试
我们可以在那里使用OVER(ORDER BY ID)
,结果也是一样的。但是然后会使用默认值RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
并且存在效率差异(ROWS
应该首选运行总计。)
@Aaron Bertrand有一篇很棒的文章,对各种计算累计总计的方法进行了全面测试: Best approaches for running totals – updated for SQL Server 2012
对于以前版本的SQL-Server,您必须使用其他方法,例如自联接,递归CTE或游标。这是一个光标解决方案,盲目地从Aaron的博客中复制,表格和列根据您的问题调整:
DECLARE @cd TABLE
( [ID] int PRIMARY KEY,
[debit] int,
[credit] int,
[sum_debit] int
);
DECLARE
@ID INT,
@debit INT,
@credit INT,
@RunningTotal INT = 0 ;
DECLARE c CURSOR
LOCAL STATIC FORWARD_ONLY READ_ONLY
FOR
SELECT ID, debit, credit
FROM CreditData
ORDER BY ID ;
OPEN c ;
FETCH NEXT FROM c INTO @ID, @debit, @credit ;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @RunningTotal = @RunningTotal + (@debit - @credit) ;
INSERT @cd (ID, debit, credit, sum_debit )
SELECT @ID, @debit, @credit, @RunningTotal ;
FETCH NEXT FROM c INTO @ID, @debit, @credit ;
END
CLOSE c;
DEALLOCATE c;
SELECT ID, debit, credit, sum_debit
FROM @cd
ORDER BY ID ;
中进行测试
答案 1 :(得分:2)
假设“have”是您的数据表,这应该是ANSI SQL解决方案:
select h.*, sum(i.debit) as debsum, sum(i.credit) as credsum, sum(i.debit) - sum(i.credit) as rolling_sum
from have h inner join have i
on h.id >= i.id
group by h.id, h.debit, h.credit
order by h.id
通常,解决方案是将行连接到行之前的所有行,然后提取这些行的总和,然后按所有内容进行分组,以按照预期返回到一行。例如this question。