我正在尝试根据之前的3个月计算销售预测,这可能是实际的或预测的。
company_id Year Month Actuals Forecast
123456 2014 1 10
123456 2014 2 15
123456 2014 3 17
123456 2014 4 14.00
123456 2014 5 15.33
123456 2014 6 15.44
123456 2014 7 14.93
Month 4 = (10+15+17)/3
Month 5 = (15+17+14)/3
Month 6 = (17+14+15.33)/3
Month 7 = (14+15.33+15.44)/3
假设我想计算每个公司未来18个月的预测。
我正在查看去年的数据。一些公司有例如2个月的数据和其他12个月等等。
我搜索并发现了许多不同的解决方案,但所有这些解决方案都只考虑了实际情况。
我想我必须做一个递归的CTE,但我无法弄明白。
请帮助:)
答案 0 :(得分:1)
在我尝试回答您的问题时,我还有另一个问题可以为您的问题提供更多答案:Calculate forecast average using recursive CTE
小提琴:http://sqlfiddle.com/#!6/9ac4a/12/0
WITH T AS
(
SELECT 1 AS [month], CAST(10 AS DECIMAL(28,2)) AS [forecast], CAST(-5 AS DECIMAL(28,2)) AS three_months_ago_forecast, CAST(9 AS decimal(28,2)) AS two_months_ago_forecast, CAST(26 AS decimal(28,2)) as one_month_ago_forecast
UNION ALL
SELECT 2,CAST(15 AS DECIMAL(28,2)), CAST(9 AS decimal(28,2)), CAST(26 AS decimal(28,2)), CAST(10 AS DECIMAL(28,2))
UNION ALL
SELECT 3,CAST(17 AS DECIMAL(28,2)), CAST(26 AS decimal(28,2)), CAST(10 AS DECIMAL(28,2)), CAST(15 AS DECIMAL(28,2))
),
LT AS -- LastForecast
(
SELECT *
FROM T
WHERE [month] = 3
),
FF AS -- Future Forecast
(
SELECT *
FROM LT
UNION ALL
SELECT
FF.[month] + 1 AS [month],
CAST( (FF.forecast * 4 - FF.three_months_ago_forecast) / 3 AS decimal(28,2)) AS forecast,
FF.two_months_ago_forecast as three_months_ago_forecast,
FF.one_month_ago_forecast as two_months_ago_forecast,
FF.forecast as one_month_ago_forecast
FROM FF
WHERE
FF.[month] < 12
)
SELECT * FROM T
WHERE [month] < 3
UNION ALL
SELECT * FROM FF
答案 1 :(得分:1)
所以你想根据之前的移动平均线移动平均值:) 我认为在SQL Server上编程时,总是必须意识到哪些任务更适合基于集合的方法,哪些更常规的逐行方法。如果你问我,你的任务非常适合简单的逐行处理。这是一个例子
declare @temp table ([Month] int, Actual decimal(29, 2), Forecast decimal(29, 2))
declare @month int
insert into @temp (
[Month], Actual
)
select 1, 10 union all
select 2, 15 union all
select 3, 17
select @month = isnull(max([Month]) + 1, 1) from @temp
while @month <= 18
begin
insert into @temp (
[Month], Forecast
)
select
@month, avg(a.value) as Forecast
from (
select top 3 isnull(Actual, Forecast) as value
from @temp
order by [Month] desc
) as a
select @month = @month + 1
end
select * from @temp