sql server - TSQL calculate row value based on value in previous row in same column -


i have dataset need calculate value each row depends on value in previous row of same column. or 1 when there no previous row. need on different partitions.

the formula looks this: factor = (previous factor or 1 if not exist) * (1 + div / nav) needs partitioned inst_id.

i prefer avoid cursor. maybe cte recursion - cannot head around - or way?

i know code not work cannot reference same column, way of showing i'm trying do:

select dato, inst_id, nav, div      , (1 + div / nav ) * isnull(lag(factor, 1) on (partition inst_id order date), 1) factor @tmp 

so test data need these results in factor column below. please ignore rounding issues, calculated in excel:

date     inst_id    nav     div     factor 11-04-2012  16  57.5700     5.7500  1.09987841 19-04-2013  16  102.8600    10.2500 1.20948130 29-04-2014  16  65.9300     16.7500 1.51675890 08-04-2013  29  111.2736    17.2500 1.15502333 10-04-2014  29  101.9650    16.3000 1.33966395 15-04-2015  29  109.5400    7.5000  1.43138825 27-04-2016  29  94.2500     0.4000  1.43746311 15-04-2015  34  159.1300    11.4000 1.07163954 27-04-2016  34  124.6100    17.6000 1.22299863 26-04-2017  34  139.7900    9.2000  1.30348784 01-04-2016  38  99.4600     0.1000  1.00100543 26-04-2017  38  102.9200    2.1000  1.02143014 

test data:

declare @tmp table(dato date, inst_id int, nav decimal(26,19), div decimal(26,19), factor decimal(26,19)) insert @tmp (dato, inst_id, nav, div) values ('2012-04-11', 16, 57.57, 5.75), ('2013-04-19', 16, 102.86, 10.25), ('2014-04-29', 16, 65.93, 16.75), ('2013-04-08', 29, 111.273577, 17.25), ('2014-04-10', 29, 101.964994, 16.3), ('2015-04-15', 29, 109.54, 7.5), ('2016-04-27', 29, 94.25, 0.4), ('2015-04-15', 34, 159.13, 11.4), ('2016-04-27', 34, 124.61, 17.6), ('2017-04-26', 34, 139.79, 9.2) 

i'm on microsoft sql server enterprise 2016 (and use ssms 2016).

you can use (if div , nav >0):

select a.* , exp(sum( log(1+div/nav) ) on (partition inst_id order dato) )as fact_new @tmp 

actually need equivalent of aggregate function multiply() on .... using log theorem: log(m*n) = log(m) + log (n) can it; example:

declare @x1 numeric(10,4)=5 declare @x2 numeric(10,4)=7 select @x1*@x2 s1, exp(log(@x1)+log(@x2)) s2 

output:

+------------+---------+-------------------------+------------------------+--------+------------------+ |    dato    | inst_id |           nav           |          div           | factor |     fact_new     | +------------+---------+-------------------------+------------------------+--------+------------------+ | 2012-04-11 |      16 |  57.5700000000000000000 |  5.7500000000000000000 | null   |   1.099878408893 | | 2013-04-19 |      16 | 102.8600000000000000000 | 10.2500000000000000000 | null   | 1.20948130303111 | | 2014-04-29 |      16 |  65.9300000000000000000 | 16.7500000000000000000 | null   | 1.51675889783963 | | 2013-04-08 |      29 | 111.2735770000000000000 | 17.2500000000000000000 | null   |   1.155023325977 | | 2014-04-10 |      29 | 101.9649940000000000000 | 16.3000000000000000000 | null   | 1.33966395090911 | | 2015-04-15 |      29 | 109.5400000000000000000 |  7.5000000000000000000 | null   | 1.43138824917236 | | 2016-04-27 |      29 |  94.2500000000000000000 |  0.4000000000000000000 | null   | 1.43746310646293 | | 2015-04-15 |      34 | 159.1300000000000000000 | 11.4000000000000000000 | null   |   1.071639539998 | | 2016-04-27 |      34 | 124.6100000000000000000 | 17.6000000000000000000 | null   | 1.22299862758278 | | 2017-04-26 |      34 | 139.7900000000000000000 |  9.2000000000000000000 | null   | 1.30348784264639 | +------------+---------+-------------------------+------------------------+--------+------------------+ 

Comments

Popular posts from this blog

angular - Ionic slides - dynamically add slides before and after -

minify - Minimizing css files -

Add a dynamic header in angular 2 http provider -