[英]How to calculate MTD given daily account balance in SQL Server?
我有一個帶有列[accountid]
, [DateEnding]
和[AccountBalance]
。 我需要在使用當月余額減去從上月的每一個最后一天的賬戶余額來計算MTD accountid
。
到目前為止,我有這個:
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;
在這里,對於每個不同的帳戶,我們都會根據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
對於這個問題,第一個答案似乎有點復雜(此處不需要“交叉申請”)。
以下內容可能對您來說更容易一些:我首先在子查詢“ 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.