Ben's answer to using a windowing clause that seems to care about your updated requirements:
select eventno, eventtype, totalcharge, remainingqty, outqty, initial_charge - case when running_outqty = 0 then 0 else (running_outqty / 100) * initial_charge end as remainingcharge from ( select eventno, eventtype, totalcharge, remainingqty, outqty, first_value(totalcharge) over (partition by null order by eventno desc) as initial_charge, sum(outqty) over (partition by null order by eventno desc rows between unbounded preceding and current row) as running_outqty from t42 );
Also, it gives 19.2 instead of 12.8 for the third line, but this is what your formula suggests:
EVENTNO EVENT TOTALCHARGE REMAININGQTY OUTQTY REMAININGCHARGE ---------- ----- ----------- ------------ ---------- --------------- 4 ACQ 32 100 0 32 3 OTHER 100 0 32 2 OUT 60 40 19.2 1 OUT 0 60 0
If I add another split so that it starts from 60 to zero in two steps, with another record outside OUT in the mix, too:
EVENTNO EVENT TOTALCHARGE REMAININGQTY OUTQTY REMAININGCHARGE ---------- ----- ----------- ------------ ---------- --------------- 6 ACQ 32 100 0 32 5 OTHER 100 0 32 4 OUT 60 40 19.2 3 OUT 30 30 9.6 2 OTHER 30 0 9.6 1 OUT 0 30 0
There is an assumption that the remaining amount is consistent, and you can effectively track the current amount of what was before, but from the data you showed it looks plausible. The internal query calculates that the total is performed for each row, and the external query performs the calculation; which can be compressed, but hopefully will be clearer like this ...
source share