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

TSQL 查询父子层级关系表中的无效循环引用映射实现方案

实现思路
  • 第一步:校验规则1(仅自映射无效),筛选出父节点只有「自身映射」一条记录、没有其他子节点映射的无效数据
  • 第二步:用递归CTE遍历所有父子链路,同时拼接路径字符串避免重复匹配,一旦发现链路中出现重复节点即可判定为循环,覆盖规则2(直接反向引用)和规则3(间接反向引用)的场景
  • 最后合并两类无效记录,附带具体无效原因和循环路径输出
完整实现代码
;WITH
-- 规则1:仅映射自身的无效记录
Rule1_Invalid AS (
    SELECT ParentId, ChildId, 'INVALID : 父节点仅映射自身' AS InvalidReason
    FROM @Data d1
    WHERE ParentId = ChildId
    AND NOT EXISTS (
        SELECT 1 FROM @Data d2 
        WHERE d2.ParentId = d1.ParentId 
        AND d2.ChildId <> d2.ParentId
    )
),
-- 递归遍历所有链路,记录路径避免无限递归
RecursiveCTE AS (
    SELECT 
        ParentId, 
        ChildId,
        CAST(CONCAT('|', ParentId, '|', ChildId, '|') AS VARCHAR(MAX)) AS Path,
        1 AS Level
    FROM @Data
    WHERE ParentId <> ChildId

    UNION ALL

    SELECT 
        r.ParentId,
        t.ChildId,
        CAST(CONCAT(r.Path, t.ChildId, '|') AS VARCHAR(MAX)),
        r.Level + 1
    FROM RecursiveCTE r
    JOIN @Data t ON r.ChildId = t.ParentId
    WHERE t.ParentId <> t.ChildId
    AND CHARINDEX(CONCAT('|', t.ChildId, '|'), r.Path) = 0
),
-- 规则2、3:存在循环引用的无效记录
Rule2_3_Invalid AS (
    SELECT DISTINCT
        d.ParentId,
        d.ChildId,
        CONCAT('INVALID : 存在循环路径 ', REPLACE(TRIM('|' FROM r.Path), '|', ' > ')) AS InvalidReason
    FROM @Data d
    JOIN RecursiveCTE r 
        ON d.ParentId = r.ParentId 
        AND CHARINDEX(CONCAT('|', d.ChildId, '|'), r.Path) > 0
    WHERE CHARINDEX(CONCAT('|', d.ParentId, '|'), STUFF(r.Path, 1, CHARINDEX(CONCAT('|', d.ChildId, '|'), r.Path), '')) > 0
)
-- 合并输出所有无效记录
SELECT ParentId, ChildId, InvalidReason FROM Rule1_Invalid
UNION ALL
SELECT ParentId, ChildId, InvalidReason FROM Rule2_3_Invalid
OPTION (MAXRECURSION 100);
输出说明

运行后会返回测试数据中标注的全部8条无效记录,每条记录都附带对应的无效原因和完整循环路径,可直接匹配注释中标记的无效场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:06:08