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

SQL使用CTE填充缺失数据 实现气象数据1分钟粒度致密化

问题核心原因

你当前的写法存在两个核心问题,无法满足致密化需求:

  • 仅生成了连续时间序列,没有和全量气象站点做笛卡尔积,导致无观测数据的站点不会出现在对应时间点的结果中
  • 没有实现 NULL 值的前向填充逻辑,缺失的观测数据无法用最近的历史值补全

调整方案

1. 核心逻辑调整

首先新增CTE获取所有去重的站点列表,再生成「1分钟时间 × 全量站点」的完整基准表,最后对每个站点分区做最近值填充即可。

2. 调整后SQL代码

DECLARE @FromDate DateTime = '2021-01-01 00:00:00.000',
        @ToDate   DateTime = '2021-08-01 00:00:00.000'

;WITH DateCte (DateTime) AS
(
    SELECT @FromDate 
    UNION ALL
    SELECT DATEADD(MINUTE, 1, DateTime)
    FROM DateCte
    WHERE DateTime < @ToDate
),
-- 新增:获取所有需要补全的去重站点列表
SiteCte AS (
    SELECT DISTINCT Name_En
    FROM [ODW].[QMD].[LastObservations]
    WHERE Local_Time >= @FromDate AND Local_Time <= @ToDate
),
-- 新增:生成 时间×站点 的完整致密化基准表
FullBaseCte AS (
    SELECT DateTime, Name_En
    FROM DateCte
    CROSS JOIN SiteCte
)
SELECT
    f.DateTime,
    -- 前向填充最近的观测时间,无历史值则为NULL可根据业务调整
    LAST_VALUE(DATEADD(mi, DATEDIFF(mi, 0, l.Local_Time), 0)) IGNORE NULLS OVER (
        PARTITION BY f.Name_En ORDER BY f.DateTime 
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS [Local Time],
    f.Name_En,
    -- 前向填充最近的降雨量,无历史值则为NULL可根据业务调整
    LAST_VALUE(l.Rainfall) IGNORE NULLS OVER (
        PARTITION BY f.Name_En ORDER BY f.DateTime 
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS [Value]
FROM FullBaseCte f
LEFT OUTER JOIN [ODW].[QMD].[LastObservations] l 
    ON f.DateTime = DATEADD(mi, DATEDIFF(mi, 0, l.Local_Time), 0) 
    AND l.Name_En = f.Name_En
    AND l.Local_Time >= @FromDate
    AND l.Local_Time <= @ToDate
ORDER BY f.DateTime
OPTION (MaxRecursion 0)

3. 低版本SQL Server兼容写法

如果你使用的SQL Server版本低于2022,不支持IGNORE NULLS参数,可以用分组标记法实现前向填充:

-- 前面的DateCte、SiteCte、FullBaseCte逻辑不变,修改外层查询即可
SELECT
    DateTime,
    MAX([Local Time]) OVER (PARTITION BY Name_En, grp) AS [Local Time],
    Name_En,
    MAX(Value) OVER (PARTITION BY Name_En, grp) AS Value
FROM (
    SELECT
        f.DateTime,
        DATEADD(mi, DATEDIFF(mi, 0, l.Local_Time), 0) AS [Local Time],
        f.Name_En,
        l.Rainfall AS [Value],
        -- 给每个非空值及后续的空值分配相同的分组标记
        SUM(CASE WHEN l.Rainfall IS NOT NULL THEN 1 ELSE 0 END) OVER (
            PARTITION BY f.Name_En ORDER BY f.DateTime
        ) AS grp
    FROM FullBaseCte f
    LEFT OUTER JOIN [ODW].[QMD].[LastObservations] l 
        ON f.DateTime = DATEADD(mi, DATEDIFF(mi, 0, l.Local_Time), 0) 
        AND l.Name_En = f.Name_En
        AND l.Local_Time >= @FromDate
        AND l.Local_Time <= @ToDate
) t
ORDER BY DateTime

内容的提问来源于stack exchange,提问作者Monib Saadi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 22:57:05