使用上一行中的值计算信息

时间:2013-01-23 16:59:20

标签: sql sql-server sql-server-2008 cursor common-table-expression

我有每个帐户的当前余额,我需要减去交易的净额以创建过去24个月的上个月的最终余额。下面是一个示例数据集;

create table txn_by_month (
memberid varchar(15)
,accountid varchar(15)
,effective_year varchar(4)
,effective_month varchar(2)
,balance money
,netamt money
,prev_mnthendbal money)

insert into txn_by_month values
(10001,111222333,2012,12,634.15,-500,1134.15)
,(10001,111222333,2012,11,NULL,-1436,NULL)
,(10001,111222333,2012,10,NULL,600,NULL)
,(10002,111333444,2012,12,1544.20,1650,-105.80)
,(10002,111333444,2012,11,NULL,1210,NULL)
,(10002,111333444,2012,10,NULL,-622,NULL)
,(10003,111456456,2012,01,125000,1200,123800)
,(10003,111456456,2011,12,NULL,1350,NULL)
,(10003,111456456,2011,11,NULL,-102,NULL)

正如您所看到的,我已经有一个表格,列出了每个月的所有交易总额。我只需要在第一行计算上个月的结束余额,然后将其降低到第二行,第三行等。我一直在尝试使用CTE,但我并不过分熟悉它们,而且似乎暂时停滞不前。这就是我所拥有的;

;
WITH CTEtest AS
(SELECT ROW_NUMBER() OVER (PARTITION BY memberid order by(accountid)) AS Sequence
,memberid
,accountid
,prev_mnthendbal
,netamt
FROM txn_by_month)

select c1.memberid
,c1.accountid
,c1.sequence
,c2.prev_mnthendbal as prev_mnthendbal
,c1.netamt, 
COALESCE(c2.prev_mnthendbal, 0) - COALESCE(c1.netamt, 0) AS cur_mnthendbal
FROM CTEtest AS c1
LEFT OUTER JOIN CTEtest AS c2 
ON c1.memberid = c2.memberid 
and c1.accountid = c2.accountid 
and c1.Sequence = c2.Sequence + 1

这仅适用于序列= 2.我知道我的问题是我需要将我的cur_mnthendbal值降低到下一行,但我似乎无法理解如何。我需要另一个CTE吗?

非常感谢任何帮助!

编辑:也许我需要更好地解释它....如果我有这个; enter image description here

第2行的余额将是第1行($ 1,134.15)的prev_mnthendbal。然后第2行的prev_mnthendbal将是余额 - 净价($ 1,134.15 - ( - $ 1,436)= $ 2,570.15)。我一直在尝试使用CTE,但我似乎无法弄清楚如何使用前一行的prev_mnthendbal填充余额字段(因为在余额可用之前不会计算)。也许我不能使用CTE?我需要使用光标吗?

2 个答案:

答案 0 :(得分:1)

事实证明,我需要将运行总计与我开始使用的顺序CTE结合起来。

;
with CTEtest AS
    (SELECT ROW_NUMBER() OVER (PARTITION BY memberid order by effective year, effective month desc) AS Sequence, *
    FROM txn_by_month)

,test
as (select * , balance - netamt as running_sum from CTEtest where sequence = 1

union all

select t.*, t1.running_sum - t.netamt from CTEtest t inner join test t1

on t.memberid = t1.memberid and t.sequence = t1.Sequence+1 where t.sequence > 1)

select * from test
order by memberid, Sequence

希望将来可以帮助其他人。

答案 1 :(得分:0)

参见LEAD / LAG分析函数。