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

SQL递归CTE拆分停机记录日期范围:未生成预期行数

递归CTE生成每日停机记录的逻辑错误分析

核心错误原因:递归方向与终止条件不匹配

你的问题出在递归步长和终止条件未适配日期ID的大小关系:

  • 异常记录的Date_ID_Down=7432大于Date_ID_Up=7402,说明这条停机记录的日期范围是从更大的日期ID(更晚的实际日期)到更小的日期ID(更早的实际日期)。
  • 如果你的递归CTE写死了递增步长(比如Current_Date_ID + 1)或错误的终止条件(比如Current_Date_ID < Date_ID_Up),会导致递归仅执行1次就触发终止,最终只生成锚点行(7432)和1次递归行,共2行。

常见的具体错误场景

  1. 终止条件比较方向错误
    若递归成员的终止条件写为Current_Date_ID < Date_ID_Up,对于Date_ID_Down=7432、Date_ID_Up=7402的记录:

    • 锚点行的Current_Date_ID=7432,第一次递归后得到7431,此时判断7431 < 7402不成立,递归直接停止,仅生成2行。
  2. 递归步长符号错误
    若递归成员写死了递增步长(Current_Date_ID + 1),对于上述反向范围的记录,每次递归会离目标7402越来越远,终止条件快速触发,同样只生成少量行。

修正方案:统一处理日期范围的正向递归

先统一每条记录的起止日期顺序,再按固定方向递归,避免因日期ID大小反转导致的错误:

WITH RecursiveCTE AS (
    -- 锚点成员:统一起止日期,取最小ID为起始,最大ID为结束
    SELECT
        CASE WHEN Date_ID_Down <= Date_ID_Up THEN Date_ID_Down ELSE Date_ID_Up END AS CurrentDateID,
        CASE WHEN Date_ID_Down <= Date_ID_Up THEN Date_ID_Down ELSE Date_ID_Up END AS New_Down,
        CASE WHEN Date_ID_Down <= Date_ID_Up THEN Date_ID_Down ELSE Date_ID_Up END AS New_Up,
        -- 保留原始起止ID用于后续逻辑(可选)
        Date_ID_Down AS Original_Down,
        Date_ID_Up AS Original_Up,
        -- 其他需要保留的字段
        *
    FROM @DowntimeFact

    UNION ALL

    -- 递归成员:按递增方向生成每日记录
    SELECT
        CurrentDateID + 1 AS CurrentDateID,
        CurrentDateID + 1 AS New_Down,
        CurrentDateID + 1 AS New_Up,
        Original_Down,
        Original_Up,
        -- 其他字段
        r.*
    FROM RecursiveCTE r
    -- 终止条件:当前日期ID未达到最大的结束ID
    WHERE CurrentDateID < CASE WHEN r.Original_Down <= r.Original_Up THEN r.Original_Up ELSE r.Original_Down END
)
-- 最终查询:输出每日的停机记录
SELECT 
    New_Down, 
    New_Up,
    -- 其他需要的字段
FROM RecursiveCTE
ORDER BY Original_Down, Original_Up, CurrentDateID;

这个方案会自动适配Date_ID_Down大于或小于Date_ID_Up的情况,确保每条记录都能生成完整的每日行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 00:19:52