Reputation: 21
I have spent some time to figure out the solutions using lag functionality as well as max functions. But this works fine when the operation is a sum or diff and not for multiplication.
Below is the original table:
id a b c
1 100 0.02 0
2 0.030 0
3 0.040 0
4 0.05 0
Expected result:
id a b c
1 100 0.02 102
2 0.030 105.06
3 0.040 109.2624
4 0.05 114.72552
Where c is
case when id =1 then (a + a*b)
else prev row of c(Lag c) +prev row of c(Lag c) * b
exception for id = 1:
c = (a + a*b)= 100 +100*0.02 = 102
id = 2:
c = 102 +102*0.03 = 105.06
id = 3:
c = 105.06 +105.06*0.04 = 109.2624
Tried multiple queries using lag and max functions. Able to do this easily in excel unlike sql.
Thank you for your help in advance!
Upvotes: 2
Views: 680
Reputation: 102
Sum:
--drop table test
create table test(
id numeric identity(1,1)
,a numeric
,b numeric
)
insert into test (a,b)values(100, 2)
insert into test (a,b)values(null, 3)
insert into test (a,b)values(null, 4)
insert into test (a,b)values(null, 5)
select id, a, b,
SUM( case when id = (select top 1 id from test) then (a+b) else b end) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as result
from test
Multiplication:
select id, a, b,
exp(SUM( case when id = (select top 1 id from test) then log(a*b) else log(b) end) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) as result
from test
Upvotes: -1
Reputation: 1270431
One method is a recursive CTE. Another method is to implement a PRODUCT()
window function. Fortunately, you can do this using some arithmetic.
So, the multiplication factor is:
select t.*,
exp(sum(log(1 + b)) over (order by id)) as factor
from t;
We can then do the complete arithmetic as:
select t.*,
max(a) over () * exp(sum(log(1 + b)) over (order by id)) as c
from t;
As written, this should work in both Oracle and SQL Server, your original tags.
Here is a SQL Fiddle.
Upvotes: 2