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

递归CTE中UNION ALL阶段过滤ROW_NUMBER()=1行的实现方法

物料清单递归展开:在UNION ALL阶段过滤最新版本完全可行

这是解决递归层级中每一层都只取物料最新版本BOM行的正确方案,比仅在CTE外部过滤靠谱得多。

原因很简单:如果不在递归迭代时过滤旧版本,旧的BOM行已经关联了对应的子物料,这些错误的关联会被带入下一层递归,最终整个物料层级链都会出错——哪怕最后在外层过滤rn2=1,那些已经生成的错误子件数据也没法消除。

修改后的简化SQL示例

WITH BomExplosion AS (
    -- 锚点成员:获取第一层级的最新版本BOM行
    SELECT 
        parent_mat = Matnr,
        child_mat = Idnrk,
        quantity = Menge,
        level = 1
    FROM (
        SELECT 
            Matnr,
            Idnrk,
            Menge,
            -- 按物料分组,取版本最高的行
            ROW_NUMBER() OVER (PARTITION BY Matnr ORDER BY Version DESC) AS rn
        FROM Bom
    ) t
    WHERE rn = 1

    UNION ALL

    -- 递归成员:每一层都先筛选当前父物料的最新版本BOM行
    SELECT 
        parent_mat = be.child_mat,
        child_mat = b.Idnrk,
        quantity = b.Menge,
        level = be.level + 1
    FROM (
        SELECT 
            Matnr,
            Idnrk,
            Menge,
            -- 同样按物料分组取最新版本
            ROW_NUMBER() OVER (PARTITION BY Matnr ORDER BY Version DESC) AS rn2
        FROM Bom
    ) b
    JOIN BomExplosion be ON b.Matnr = be.child_mat
    WHERE b.rn2 = 1 -- 关键:在这里过滤,只让最新版本进入下一层递归
)
SELECT * FROM BomExplosion;

核心逻辑说明

在递归成员里,先通过子查询给当前要处理的所有BOM行加上行号rn2,按物料分组并按版本降序排序,然后只保留rn2=1的行(也就是最新版本)再去关联递归CTE的上一层数据。这样每一次迭代都只会用最新版本的BOM行去展开子物料,从根源上避免了旧版本数据污染整个递归链。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 03:52:16