SQL - 计算预测平均值

时间:2016-02-01 17:26:41

标签: sql sql-server-2008-r2 average common-table-expression recursive-query

我正在尝试根据之前的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,但我无法弄明白。

请帮助:)

2 个答案:

答案 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