You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将R中计算的SARIMA方程应用于SQL Server?

没问题!我来帮你把R里得到的SARIMA模型落地到SQL Server里。先拆解清楚你的模型结构,再一步步写SQL逻辑实现预测。

把SARIMA(2,0,0)(1,1,0)[12]模型迁移到SQL Server

首先,先明确你的模型结构:这是一个月度季节性SARIMA模型(周期12),做了1次季节性差分,非季节性部分是2阶自回归(AR(2)),季节性部分是1阶自回归(SAR(1)),没有移动平均(MA)项。

模型的数学表达式

先把模型转化成可计算的公式:

  1. 首先定义季节性差分序列:( D_t = X_t - X_{t-12} ),其中( X_t )是t时刻的原始序列值,( X_{t-12} )是12个月前的原始值。
  2. 你的SARIMA模型对差分后的序列( D_t )的预测公式(忽略随机误差项,预测时默认误差为0)是:
    [
    \hat{D}t = 0.3973 \times D{t-1} + 0.4954 \times D_{t-2} - 0.4858 \times D_{t-12}
    ]
  3. 还原回原始序列的预测值:
    [
    \hat{X}_t = \hat{D}t + X{t-12}
    ]

在SQL Server中实现的步骤

1. 基础预测(拟合历史数据)

假设你的原始时间序列数据存在表TimeSeriesData,包含Date(日期,比如DATE类型,月度数据)和Value(序列值,数值类型)。我们用窗口函数LAG()来获取滞后值,计算差分和预测:

-- 定义模型系数(方便后续修改)
DECLARE @ar1 FLOAT = 0.3973;
DECLARE @ar2 FLOAT = 0.4954;
DECLARE @sar1 FLOAT = -0.4858;

WITH TimeSeriesWithMetrics AS (
    SELECT
        Date,
        Value,
        -- 计算季节性差分 D_t = X_t - X_{t-12}
        Value - LAG(Value, 12) OVER (ORDER BY Date) AS D_t,
        -- 获取滞后1期的D值
        LAG(Value - LAG(Value, 12) OVER (ORDER BY Date), 1) OVER (ORDER BY Date) AS D_t_minus_1,
        -- 获取滞后2期的D值
        LAG(Value - LAG(Value, 12) OVER (ORDER BY Date), 2) OVER (ORDER BY Date) AS D_t_minus_2,
        -- 获取滞后12期的D值
        LAG(Value - LAG(Value, 12) OVER (ORDER BY Date), 12) OVER (ORDER BY Date) AS D_t_minus_12,
        -- 获取滞后12期的原始值 X_{t-12}
        LAG(Value, 12) OVER (ORDER BY Date) AS X_t_minus_12
    FROM TimeSeriesData
)
SELECT
    Date,
    Value AS Actual_Value,
    -- 计算预测的差分序列值
    @ar1 * ISNULL(D_t_minus_1, 0) + @ar2 * ISNULL(D_t_minus_2, 0) + @sar1 * ISNULL(D_t_minus_12, 0) AS Predicted_D_t,
    -- 计算原始序列的预测值
    (@ar1 * ISNULL(D_t_minus_1, 0) + @ar2 * ISNULL(D_t_minus_2, 0) + @sar1 * ISNULL(D_t_minus_12, 0)) + ISNULL(X_t_minus_12, 0) AS Predicted_Value
FROM TimeSeriesWithMetrics
-- 过滤掉没有足够滞后数据的初始行(前14个月,因为需要滞后12+2期)
WHERE Date >= (SELECT DATEADD(MONTH, 14, MIN(Date)) FROM TimeSeriesData)
ORDER BY Date;

2. 滚动预测未来季度(3个月)

如果要预测未来3个月的数值,需要用递归CTE来迭代计算,因为每一步的预测值依赖于前一步的结果:

DECLARE @ar1 FLOAT = 0.3973;
DECLARE @ar2 FLOAT = 0.4954;
DECLARE @sar1 FLOAT = -0.4858;
DECLARE @forecastMonths INT = 3; -- 预测未来3个月

-- 先获取足够的历史数据(至少14行,用于提供滞后12、2、1期的值)
WITH HistoricData AS (
    SELECT
        Date,
        Value,
        Value - LAG(Value, 12) OVER (ORDER BY Date) AS D_t
    FROM TimeSeriesData
    ORDER BY Date DESC
    OFFSET 0 ROWS FETCH NEXT 14 ROWS ONLY
),
-- 按日期升序排列历史数据,并添加行号
OrderedHistoric AS (
    SELECT
        Date,
        Value,
        D_t,
        ROW_NUMBER() OVER (ORDER BY Date) AS RowNum
    FROM HistoricData
),
-- 递归生成预测
RecursiveForecast AS (
    -- 基础部分:历史数据
    SELECT
        Date,
        Value,
        D_t,
        RowNum
    FROM OrderedHistoric
    UNION ALL
    -- 递归部分:预测未来月份
    SELECT
        DATEADD(MONTH, 1, prev.Date) AS Date,
        -- 计算预测的X_t = 预测的D_t + X_{t-12}
        (@ar1 * prev.D_t + @ar2 * LAG(prev.D_t, 1) OVER (ORDER BY prev.RowNum) + @sar1 * LAG(prev.D_t, 12) OVER (ORDER BY prev.RowNum)) + 
        LAG(prev.Value, 12) OVER (ORDER BY prev.RowNum) AS Value,
        -- 计算预测的D_t = 预测的X_t - X_{t-12}
        @ar1 * prev.D_t + @ar2 * LAG(prev.D_t, 1) OVER (ORDER BY prev.RowNum) + @sar1 * LAG(prev.D_t, 12) OVER (ORDER BY prev.RowNum) AS D_t,
        prev.RowNum + 1 AS RowNum
    FROM RecursiveForecast prev
    WHERE prev.RowNum < (SELECT MAX(RowNum) FROM OrderedHistoric) + @forecastMonths
)
SELECT
    Date,
    Value,
    CASE WHEN RowNum <= (SELECT MAX(RowNum) FROM OrderedHistoric) THEN 'Actual' ELSE 'Forecast' END AS Data_Type
FROM RecursiveForecast
ORDER BY Date;

注意事项

  • 初始值处理:前14个月的预测值因为缺乏足够的滞后数据,结果不可靠,所以基础预测里加了过滤条件。
  • 时间粒度调整:如果你的数据是周度/季度,只需修改DATEADD的参数(比如WEEK/QUARTER)和LAG的阶数(比如周度周期用52)。
  • 系数维护:把系数定义成变量,后续如果模型更新,直接修改变量值即可,不用改SQL逻辑。

内容的提问来源于stack exchange,提问作者Hein Thetard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:02:19