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

如何使用递归CTE查询SQL Server中特定子节点的完整层级深度?

问题分析

你当前使用的递归CTE是自上而下的遍历逻辑:从根节点(p_key = 'old'的行)开始,逐层向下查询所有子节点,所以默认会返回全量链路数据。你之前在UNION ALL的递归查询段加WHERE筛选失败,是因为递归过程中直接过滤会打断链路遍历,最终只能返回锚点段的深度0数据。


解决方案

方案1:仅需获取child节点的深度值

不需要修改递归逻辑,直接在CTE的最终查询语句加过滤条件即可:

WITH cte_data (c_key, p_key, depth) AS
(
    SELECT c_key, p_key, 0 AS depth
    FROM my_table
    WHERE p_key = 'old'

    UNION ALL

    SELECT c.c_key, c.p_key, o.depth + 1 AS depth
    FROM cte_data o
    INNER JOIN my_table c ON o.c_key = c.p_key
)
SELECT * 
FROM cte_data
WHERE c_key = 'child'

执行后会返回c_key = 'child'的单行结果,对应深度为2。


方案2:需要获取child到根节点的完整层级链路

推荐将递归逻辑改为自下而上遍历,直接从目标子节点出发向上找父节点,只会遍历你需要的链路,数据量较大时性能远优于全量遍历后过滤:

WITH cte_data (c_key, p_key, depth) AS
(
    -- 锚点:从目标子节点开始查询
    SELECT c_key, p_key, 0 AS depth
    FROM my_table
    WHERE c_key = 'child'

    UNION ALL

    -- 递归向上关联父节点
    SELECT o.c_key, o.p_key, c.depth + 1 AS depth
    FROM my_table o
    INNER JOIN cte_data c ON o.c_key = c.p_key
)
SELECT * 
FROM cte_data

执行后会返回完整链路:child(深度0)→teen(深度1)→adult(深度2),如果需要把根节点old也纳入结果,补充一行合并逻辑即可:

WITH cte_data (c_key, p_key, depth) AS
(
    SELECT c_key, p_key, 0 AS depth
    FROM my_table
    WHERE c_key = 'child'

    UNION ALL

    SELECT o.c_key, o.p_key, c.depth + 1 AS depth
    FROM my_table o
    INNER JOIN cte_data c ON o.c_key = c.p_key
)
SELECT c_key, p_key, depth FROM cte_data
UNION ALL
SELECT 'old' AS c_key, NULL AS p_key, MAX(depth)+1 AS depth FROM cte_data

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 08:48:03