我有一个表,其中包含列[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;
答案 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