SQL Server 2014 LAG函数运行开始和结束余额

时间:2016-09-09 15:09:04

标签: sql sql-server sql-server-2014

希望有人可以协助我试图写的查询。我正在尝试使用SQL 2014中的LAG函数编写正在运行的总计/开始和结束余额查询。不幸的是,我似乎无法使语法正确并且我想知道这是否可行。基本上,前一行的结束余额(endbal)值需要是下一行的开始余额(begbal),依此类推。结束余额计算为(开始余额 - principalcashflow)以下是我的示例查询和表变量设置:

declare @calccashflow table(
    recordid int,
    cashflowdate date,
    begbal float,
    endbal float,
    principalcashflow float,
    interestcashflow float
);

/*populate with test data */
insert into @calccashflow(recordid,cashflowdate,begbal,principalcashflow,interestcashflow)
values(1,'2016-09-01',100000000.00,100000.0,200.0);
insert into @calccashflow(recordid,cashflowdate,principalcashflow,interestcashflow)
values(2,'2016-10-01',200000.0,200.0);
insert into @calccashflow(recordid,cashflowdate,principalcashflow,interestcashflow)
values(3,'2016-11-01',300000.0,200.0);
insert into @calccashflow(recordid,cashflowdate,principalcashflow,interestcashflow)
values(4,'2016-12-01',300000.0,200.0);

/*set the ending balance of the first row to begbal-principalcashflow*/
update @calccashflow set endbal=begbal -principalcashflow where recordid=1;
SELECT  recordid, 
        cashflowdate ,
        begbal=case when recordid=1 then begbal 
                else lag(endbal,1,0) over (order by recordid) end,
        endbal=(case when recordid=1 then endbal 
                 else (case when recordid=1 then begbal 
                            else lag(endbal,1,0) over (order by recordid)    end) - principalcashflow end),
        principalcashflow,
        interestcashflow     
FROM @calccashflow

结果并不是我想要的结果,在第二排之后它们都会崩溃(见下图): Query Results

我希望看到的内容如下:

rowid  cashflowdate     begbal   endbal   principalcashflow
-----  ------------     ------   ------   -----------------
    1  2016-09-01     100000000 99900000              10000
    2  2016-10-01      99900000 99700000              20000
    3  2016-11-01      99700000 99400000              30000
    4  2016-12-01      99400000 99100000              30000

此处,前一记录的期末余额成为下一记录的期初余额。如上所述,每行的结束余额计算为(begbal-principalcashflow)。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

这是使用累积和和first_value窗口函数的一种方法。请注意,您甚至不需要更新第一条记录的endbal列。我拿出了更新。

declare @calccashflow table(
    recordid int,
    cashflowdate date,
    begbal float,
    endbal float,
    principalcashflow float,
    interestcashflow float
);

/*populate with test data */
insert into @calccashflow(recordid,cashflowdate,begbal,principalcashflow,interestcashflow)
values(1,'2016-09-01',100000000.00,100000.0,200.0);
insert into @calccashflow(recordid,cashflowdate,principalcashflow,interestcashflow)
values(2,'2016-10-01',200000.0,200.0);
insert into @calccashflow(recordid,cashflowdate,principalcashflow,interestcashflow)
values(3,'2016-11-01',300000.0,200.0);
insert into @calccashflow(recordid,cashflowdate,principalcashflow,interestcashflow)
values(4,'2016-12-01',300000.0,200.0);

with cte as (
  select recordid,
         cashflowdate,
         begbal,
         endbal = first_value(begbal) over (order by recordid) 
                  - sum(principalcashflow) over (order by recordid),
         principalcashflow,
         interestcashflow
  from @calccashflow
)
select recordid,
       cashflowdate,
       begbal = coalesce(begbal, endbal + principalcashflow),
       endbal,
       principalcashflow,
       interestcashflow
  from cte
 order by recordid;