You can unpivot the data to make the manipulation easier. Probably your original data itself you should stored for each month/year in different rows
To calculate running multiplication you can use EXP
and LOG
function. Referred from this answer.
Mutiplication aggregate operator in SQL
DECLARE @input_date DATE = '2016-02-01',
@no_of_years INT = 1
;with cte as
(select * from (values
(2013 , -1 , 3 , 4 , -10 , 4 , 6 , 13, -3, 5 , 3 , 8 , -6 ),
(2014 , 3 , 2 , -5 , 4 , 1 , 7 , 8 , -8, 11 , 9 , -1 , 4 ),
(2015 , 2 , 4 , -3 , 4 ,-8 , 2 , 1 , 9, 3 , 4 , -6 , 9 ),
(2016 , 5 , 4 , 2 , 6 , 8 , 9 , 2 , -4, -3 ,NULL, NULL , NULL ))
tc(year, jan, feb, mar ,apr, may ,jun, jul ,aug ,sep, oct, nov, dec)
)
SELECT dates,
CASE
WHEN Min(Abs(VALUE))OVER(ORDER BY dates) = 0 THEN 0
ELSE Exp(Sum(Log(Abs(NULLIF(VALUE, 0))))
OVER(ORDER BY dates))
* Round(0.5 - Count(NULLIF(Sign(Sign(VALUE) + 0.5), 1))
OVER(ORDER BY dates)%2, 0)
END
FROM cte
CROSS apply(VALUES (jan,Datefromparts(year, 1, 1)),
(feb,Datefromparts(year, 2, 1)),
(mar,Datefromparts(year, 3, 1)),
(apr,Datefromparts(year, 4, 1)),
(may,Datefromparts(year, 5, 1)),
(jun,Datefromparts(year, 6, 1)),
(jul,Datefromparts(year, 7, 1)),
(aug,Datefromparts(year, 8, 1)),
(sep,Datefromparts(year, 9, 1)),
(oct,Datefromparts(year, 10, 1)),
(nov,Datefromparts(year, 11, 1)),
(dec,Datefromparts(year, 12, 1))) tc (VALUE, dates)
WHERE dates > Dateadd(mm, -12 * @no_of_years, @input_date)
AND dates <= @input_date
SELECT year, umonth, uval FROM myTable CROSS APPLY (VALUES (1, JAN), (2, FEB), (3, MAR), (4, APR), (5, MAY), (6, JUN), (7, JUL), (8, AUG), (9, SEP), (10, OCT), (11, NOV), (12, DEC)) U(umonth, uval);
should give you the unpivoted values as well as the month numbers. – ZLK