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

如何用前一个非空值填充数据表中的空值行?

高效填充MyValue列空值为前一个非空值的方案

原始数据表

ID|Month|MyValue
1|202212|null
1|202211|bbb
1|202210|null
1|202209|null
1|202208|aaa

目标结果

ID|Month|MyValue
1|202212|bbb
1|202211|bbb
1|202210|aaa
1|202209|aaa
1|202208|aaa

核心思路

按ID分组,按Month降序排序(确保时间靠后的行优先获取最近的非空值),利用窗口函数向前填充非空值,这种方式避免了游标或循环,效率远高于逐行处理。

各数据库实现方案

MySQL 8.0+ / PostgreSQL / SQL Server

支持IGNORE NULLS版本(MySQL 8.0.22+、PostgreSQL、SQL Server)

使用LAST_VALUE窗口函数直接跳过空值,取当前行及之前的最后一个非空值:

SELECT 
    ID,
    Month,
    LAST_VALUE(MyValue IGNORE NULLS) OVER (
        PARTITION BY ID 
        ORDER BY Month DESC 
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS MyValue
FROM your_table;

MySQL 8.0.22之前版本

由于不支持IGNORE NULLS,可以用MAX()窗口函数替代(非空值会覆盖空值的最大值):

SELECT 
    ID,
    Month,
    MAX(MyValue) OVER (
        PARTITION BY ID 
        ORDER BY Month DESC 
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS MyValue
FROM your_table;

Oracle

Oracle原生支持LAST_VALUE加IGNORE NULLS,语法更简洁:

SELECT 
    ID,
    Month,
    LAST_VALUE(MyValue IGNORE NULLS) OVER (
        PARTITION BY ID 
        ORDER BY Month DESC 
        ROWS UNBOUNDED PRECEDING
    ) AS MyValue
FROM your_table;

更新原表的方案(以MySQL为例)

如果需要直接更新原表而非仅查询结果,可通过CTE关联更新:

WITH filled_data AS (
    SELECT 
        ID,
        Month,
        MAX(MyValue) OVER (
            PARTITION BY ID 
            ORDER BY Month DESC 
            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
        ) AS filled_value
    FROM your_table
)
UPDATE your_table t
JOIN filled_data fd ON t.ID = fd.ID AND t.Month = fd.Month
SET t.MyValue = fd.filled_value
WHERE t.MyValue IS NULL;

内容的提问来源于stack exchange,提问作者Brian Jones

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 03:55:10