如何在给定的SQL Server中的每日帐户余额下计算MTD?

时间:2019-01-04 17:08:30

标签: sql sql-server tsql

我有一个表,其中包含列[accountid][DateEnding][AccountBalance]。 我需要使用当月的余额并从上个月的最后一天减去每个accountid的帐户余额来计算MTD。

到目前为止,我有这个:

SELECT [accountid]
      ,[DateEnding]
      ,[AccountBalance]
     ,[AccountBalance MTD Last] = AccountBalance - FIRST_VALUE(AccountBalance) OVER (PARTITION BY accountid, YEAR(DATEADD(mm,-1,[DateEnding])), MONTH(DATEADD(mm,-1,[DateEnding])) ORDER BY [DateEnding] DESC)
FROM [test]
ORDER BY accountid, DateEnding;

2 个答案:

答案 0 :(得分:0)

在这里,对于每个不同的帐户,我们都会根据DateEnding找到可用的最新记录 然后,我们通过减去等于当前天数的天数来找到上个月的最后一天。例如,2019年4月23日,我们减去23天即可得出2019年3月1日 然后我们可以找到当天的余额。

然后将计算结果放到SELECT

SELECT Q1.accountid, 
       Q2.DateEnding , 
       Q3.EOMbalance, 
       Q2.LatestBalance, 
       Q2.LatestBalance - Q3.EOMbalance EOM
      FROM (
                SELECT Distinct t1.accountid FROM test t1
           ) Q1
        CROSS APPLY (
                        SELECT TOP 1 t2.AccountBalance LatestBalance, t2.[DateEnding] 
                            FROM test t2 
                            WHERE t2.[accountid] = Q1.accountid 
                            ORDER BY t2.[DateEnding] DESC
                    ) Q2
        CROSS APPLY (
                        SELECT Top 1 t3.AccountBalance EOMbalance 
                            FROM test t3 
                            WHERE t3.[accountid] = Q1.accountid 
                                AND t3.[DateEnding] 
                                      = dateadd(day,0 - DAY(q2.dateending), q2.dateending)
                            ORDER BY t3.[DateEnding] DESC
                    ) Q3

答案 1 :(得分:0)

对于这个问题,第一个答案似乎有点复杂(此处无需交叉申请)。

以下内容可能对您来说更容易: 我首先在子查询“ a”中查看当天的帐户余额。 然后,我在子查询“ b”中查看上个月数据的最后一天的帐户余额。

然后只需要减去两个即可显示MTD增量:

select a.accountid, 
       a.DateEnding, 
       a.AccountBalance as [Current AccountBalance], 
       b.AccountBalance as [EOM prior AccountBalance], --added for clarity
       a.AccountBalance-b.AccountBalance as [AccountBalance MTD Last]
from
    (select accountid, DateEnding, AccountBalance
    from #test 
    where DateEnding = cast(getdate() as date) 
       /* getdate() returns today's date, so this query will also be with respect to today */
    ) a
left join
    (select *
    from #test 
    where DateEnding = DATEADD(MONTH, DATEDIFF(MONTH, -1, GETDATE())-1, -1) 
       /*this returns the last day of last month, always*/
    ) b
    on a.accountid = b.accountid

以下是制作此示例数据和#test表的SQL。只需执行它即可运行自己的“ #test”表:

/*drop table #test
  drop table #dates */
create table #test ([accountid] varchar(255),[DateEnding] date, [AccountBalance] decimal(16,2))
create table #dates (rnk int,dt date)

insert into #dates (dt)
values (cast('20180101' as date))

DECLARE
  @basedate DATE,
  @d   INT
SELECT
  @basedate = '20180101',
  @d = 1

WHILE @d < (select datediff(day,cast('20180101' as date),getdate())+2)  --select datediff(day,getdate(),cast('20180101' as datetime))
BEGIN
  INSERT INTO #dates (dt)
    values (DATEADD(day, 1, (select max(dt) from #dates)))
  set @d = @d+1
END

update a 
set a.rnk = b.rnk
from #dates a
left join (select rank() over (order by dt) rnk,dt from #dates) b on a.dt = b.dt

declare @a int
set @a = 1
declare @i int
set @i = 1
while @a <20
begin
    while @i < (select max(rnk) from #dates)
    begin
        insert into #test
        values (@a,(select dt from #dates where rnk = @i),cast(rand()*1000.0+@i as decimal(16,2)))
        set @i=@i+1
    end
    set @a=@a+1
    set @i = 1
end