2013-06-27 4 views
0

я таблицу с данными в моей базе данных следующим образом:SQL - Как рассчитать процентное изменение/рост

year month sales mom  qoq yoy 
---------------- 
2010 1 80 -  - - 
2010 2 61 -23.75% - - 
2010 3 81 32.79% - - 
2010 4 94 16.05%  - 
2010 5 77 -18.09%  - 
2010 6 75 -2.60%  - 
2010 7 58 -22.67%  - 
2010 8 74 27.59%  - 
2010 9 98 32.43%  - 
2010 10 97 -1.02%  - 
2010 11 94 -3.09%  - 
2010 12 63 -32.98%  - 
2011 1 61 -3.17%  -23.75% 
2011 2 79 29.51%  29.51% 
2011 3 84 6.33%  3.70% 
2011 4 100 19.05%  6.38% 
2011 5 78 -22.00%  1.30% 
2011 6 99 26.92%  32.00% 
2011 7 78 -21.21%  34.48% 
2011 8 63 -19.23%  -14.86% 
2011 9 66 4.76%  -32.65% 
2011 10 77 16.67%  -20.62% 
2011 11 93 20.78%  -1.06% 
2011 12 94 1.08%  49.21% 

Я хочу, чтобы рассчитать ежемесячные, ежеквартальные и ежегодные продажи процентное изменение в течение каждого месяца (каждая строка), , как показано в последних 3 столбцах выше.
Как я могу достичь этого в одном наборе результатов с использованием T-SQL? Я использую SQL Server 2008 R2. Благодарю.

+0

Пожалуйста, добавьте ожидаемый выход. – TechDo

+0

Роллинг ежегодно, или год до даты? ежеквартально? –

+0

, пожалуйста, покажите, какой результат должен выглядеть и, возможно, объясните почему. – Jodrell

ответ

1

Здесь было бы удобно использовать функцию окна с LAG, но она работает только в MSSQL2012. Поэтому я использую row_number

declare @tab table (year int, month int, sales money) 

insert into @tab values 
(2010, 1, 80),(2010, 2, 61),(2010, 3, 81), 
(2010, 4, 94),(2010, 5, 77),(2010, 6, 75), 
(2010, 7, 58),(2010, 8, 74),(2010, 9, 98), 
(2010, 10, 97),(2010, 11, 94),(2010, 12, 63), 
(2011, 1, 61),(2011, 2, 79),(2011, 3, 84), 
(2011, 4, 100),(2011, 5, 78),(2011, 6, 99), 
(2011, 7, 78),(2011, 8, 63),(2011, 9, 66), 
(2011, 10, 77),(2011, 11, 93),(2011, 12, 94); 

with cte as (
    select 
     row_number() over (order by year, month) rn, 
     year, 
     month, 
     sales 
    from @tab 
) 
select 
    year, 
    month, 
    sales, 
    round((sales-(select sales from cte where cte.rn=t1.rn-1))/(select sales from cte where cte.rn=t1.rn-1)*100.0,2) as mom, 
    round((sales-(select sales from cte where cte.rn=t1.rn-4))/(select sales from cte where cte.rn=t1.rn-4)*100.0,2) as qoq, 
    round((sales-(select sales from cte where cte.rn=t1.rn-12))/(select sales from cte where cte.rn=t1.rn-12)*100.0,2) as yoy 
from cte as t1 
+0

Не могли бы вы предоставить образец с использованием LAG? – armen

+0

@ Александр спасибо этому великому .. Просто вопрос для qoq, не должен ли интервал быть 3 вместо 4? PLS, дайте мне знать –

5

Этот запрос работает только в MSSQL2012, но это план и время Exec гораздо лучше

SELECT 
    year, 
    month, 
    sales, 
    (sales - LAG(sales, 1) over (ORDER BY year, month))/LAG(sales, 1) over (ORDER BY year, month)*100 AS mom, 
    (sales - LAG(sales, 4) over (ORDER BY year, month))/LAG(sales, 4) over (ORDER BY year, month)*100 AS qoq, 
    (sales - LAG(sales, 12) over (ORDER BY year, month))/LAG(sales, 12) over (ORDER BY year, month)*100 AS yoy 
FROM @tab 
Смежные вопросы