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

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -