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

MySQL如何将列中0值替换为前一行非零值?是否需递归CTE?

用最近非零值填充0值的实现方案

你需要把数据里值为0的行,替换成它之前最近的非零行的值,先看你的示例数据(左列是原始值,右列是期望结果):

from |  to
------------
11   |  11
2    |  2
32   |  32
41   |  41
5    |  5
0    |  5
0    |  5
0    |  5
0    |  5
61   |  61
0    |  61
17   |  17
0    |  17
0    |  17
8    |  8
4    |  4   

核心结论:不需要递归CTE,现代数据库用窗口函数就能高效解决,递归CTE只是兼容旧版本的备选方案。


方法一:窗口函数实现(推荐)

不同数据库的语法略有差异,以下是主流数据库的写法:

PostgreSQL / SQL Server 2022+

直接用LAST_VALUE结合IGNORE NULLS,把0转为NULL后,取当前行及之前最近的非NULL值:

SELECT 
    "from" AS original_value,
    LAST_VALUE(CASE WHEN "from" != 0 THEN "from" END IGNORE NULLS)
        OVER (ORDER BY (SELECT 1) ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS filled_value
FROM your_table;

注:(SELECT 1)用来按数据原有顺序排序,如果你有明确的排序字段(比如主键、时间戳),替换成对应的字段即可。

不支持IGNORE NULLS的数据库(比如SQL Server旧版本、MySQL 8.0+)

用分组技巧:先给每个非零值及其后续的0值分配同一个分组ID,再取分组内的最大值(也就是那个非零值):

WITH numbered_rows AS (
    SELECT 
        "from",
        -- 累计非零值的数量,作为分组ID
        SUM(CASE WHEN "from" != 0 THEN 1 ELSE 0 END) OVER (ORDER BY (SELECT 1)) AS group_id
    FROM your_table
)
SELECT 
    "from" AS original_value,
    MAX("from") OVER (PARTITION BY group_id) AS filled_value
FROM numbered_rows;

方法二:递归CTE(仅兼容旧版本数据库)

如果你的数据库不支持窗口函数(比如MySQL 5.x),可以用递归CTE,但效率远不如窗口函数:

WITH RECURSIVE cte AS (
    -- 取第一行数据作为递归起点
    SELECT 
        ROW_NUMBER() OVER () AS row_id,
        "from" AS original_value,
        "from" AS filled_value
    FROM your_table
    LIMIT 1
    UNION ALL
    -- 逐行递归处理:当前值为0就用上一行的填充值,否则用自身值
    SELECT 
        t.row_id,
        t."from" AS original_value,
        CASE WHEN t."from" = 0 THEN c.filled_value ELSE t."from" END AS filled_value
    FROM (
        SELECT "from", ROW_NUMBER() OVER () AS row_id FROM your_table
    ) t
    JOIN cte c ON t.row_id = c.row_id + 1
)
SELECT original_value, filled_value FROM cte ORDER BY row_id;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 12:39:50