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
Post a Comment