sql - divide payments for periods -
i have total value contain user payments since registered. each year since registration date, user must pay premium membership doesn't have payed in same year. user can pay e. eg. 3 year back. or next 3 following years in advance.
rates years follows:
year | rate 2014 | 100 2015 | 100 2016 | 50 2017 | 150 2018 | 100
that's values user should pay. can transfer less or more money required. let user has payed 438$. doesn't matter when did this. 2014 or current year. want know if has payed should, fees 2014 current year.
what want divide total amount of transfers (calculated , stored in variable) each year should payed check has paid or has excess payment/underpayment.
result get:
year | rate | payed 2014 | 100 | 100 2015 | 100 | 100 2016 | 50 | 50 2017 | 150 | 150 2018 | 100 | 38
so user has payed should date , has 38$ excess payment.
using loop/cursor can that, can't think of window function use. hint? can't find how query google case.
sample (solution working looking window function equivalent)
declare @total decimal = 438 ;with data ( select *, @total - (select sum(tt.rate) (values (2013, 100), (2014, 100), (2015, 100), (2016, 100), (2017, 100), (2018, 100)) tt([year], rate) tt.[year] < t.[year]) payed (values (2013, 100), (2014, 100), (2015, 100), (2016, 100), (2017, 100), (2018, 100)) t([year], rate) ), prepared ( select d.[year], @total total, d.rate, case when isnull(d.payed, d.rate) <= 0 null when @total < d.rate @total else isnull(d.payed, d.rate) end payed data d ) select p.[year], @total total, p.rate, case when p.payed >= p.rate p.rate else p.payed end payed prepared p
if using sql server 2012+ easy calculate total outstanding (or overpaid) amount using sum() on (order by...)
.
sample data
declare @totalpaid money = 438; declare @rates table (y int, rate money); insert @rates (y, rate) values (2014, 100), (2015, 100), (2016, 50), (2017, 150), (2018, 100), (2019, 100);
query
with cte ( select y ,rate ,sum(rate) on (order y rows between unbounded preceding , current row) sumrate @rates ) ,cte2 ( select y ,rate ,sumrate ,@totalpaid - sumrate paidextra cte ) select y ,rate ,sumrate ,paidextra ,case when paidextra >= 0 rate else rate + paidextra end paid cte2 order y ;
result
+------+--------+---------+-----------+--------+ | y | rate | sumrate | paidextra | paid | +------+--------+---------+-----------+--------+ | 2014 | 100.00 | 100.00 | 338.00 | 100.00 | | 2015 | 100.00 | 200.00 | 238.00 | 100.00 | | 2016 | 50.00 | 250.00 | 188.00 | 50.00 | | 2017 | 150.00 | 400.00 | 38.00 | 150.00 | | 2018 | 100.00 | 500.00 | -62.00 | 38.00 | | 2019 | 100.00 | 600.00 | -162.00 | -62.00 | +------+--------+---------+-----------+--------+
Comments
Post a Comment