There is a table Payment
, which for example tracks the amount of money user puts into account, simplified as
=================================== Id | UserId | Amount | PayDate | =================================== 1 | 42 | 11 | 01.02.99 | 2 | 42 | 31 | 05.06.99 | 3 | 42 | 21 | 04.11.99 | 4 | 24 | 12 | 05.11.99 |
What is need is to receive a table with balance before payment moment, eg:
=============================================== Id | UserId | Amount | PayDate | Balance | =============================================== 1 | 42 | 11 | 01.02.99 | 0 | 2 | 42 | 31 | 05.06.99 | 11 | 3 | 42 | 21 | 04.11.99 | 42 | 4 | 24 | 12 | 05.11.99 | 0 |
Currently the select statement looks something like
SELECT Id, UserId, Amount, PaidDate, (SELECT sum(amount) FROM Payments nestedp WHERE nestedp.UserId = outerp.UserId AND nestedp.PayDate < outerp.PayDate) as Balance FROM Payments outerp
How can I rewrite this select to get rid of the nested aggregate selection? The database in question is SQL Server 2019.
Advertisement
Answer
Thanks to other participants’ leads I came up with a query that (seems) to work:
SELECT Id, UserId, Amount, PayDate, COALESCE(sum(Amount) over (partition by UserId order by PayDate rows between unbounded preceding and 1 preceding), 0) as Balance FROM Payments ORDER BY UserId, PayDate
Lots of related examples can be found here