With the below table of data
Customer | Amount Billed | Amount Paid | Date |
---|---|---|---|
1 | 100 | 60 | 01/01/2000 |
1 | 100 | 40 | 01/02/2000 |
2 | 200 | 150 | 01/01/2000 |
2 | 200 | 30 | 01/02/2000 |
2 | 200 | 10 | 01/03/2000 |
2 | 200 | 15 | 01/04/2000 |
I would like to create the next two columns
Customer | Amount Billed | Amount Paid | Assigned | Remainder | Date |
---|---|---|---|---|---|
1 | 100 | 60 | 60 | 40 | 01/01/2000 |
1 | 100 | 40 | 40 | 0 | 01/02/2000 |
2 | 200 | 150 | 150 | 50 | 01/01/2000 |
2 | 200 | 30 | 30 | 20 | 01/02/2000 |
2 | 200 | 10 | 10 | 10 | 01/03/2000 |
2 | 200 | 15 | 10 | -5 | 01/04/2000 |
The amount paid on each line should be removed from the amount billed and pushed onto the next line for the same customer. The process should continue until there are no more records or the remainder is < 0.
Is there a way of doing this without a cursor? Maybe a recursive CTE?
Thanks
Advertisement
Answer
As I mentioned in the comments, this is just a cumulative SUM
:
WITH YourTable AS( SELECT * FROM (VALUES(1,100,60 ,CONVERT(date,'01/01/2000')), (1,100,40 ,CONVERT(date,'01/02/2000')), (2,200,150,CONVERT(date,' 01/01/2000')), (2,200,30 ,CONVERT(date,'01/02/2000')), (2,200,10 ,CONVERT(date,'01/03/2000')), (2,200,15 ,CONVERT(date,'01/04/2000')))V(Customer,AmountBilled,AmountPaid,[Date])) SELECT Customer, AmountBilled, AmountPaid, AmountBilled - SUM(AmountPaid) OVER (PARTITION BY Customer ORDER BY [Date] ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Remainder, [Date] FROM YourTable ORDER BY Customer, [Date];
Note this returns -5
for the last row, not 5
, as 200 - 205 = -5
. If you want 5
wrap the whole expression in an absolute function.