多父节点闭包表查询全节点所有完整路径的SQL实现问题
问题核心错漏
- 锚点逻辑错误:原查询直接取所有
depth=0的closure记录作为路径起点,把所有节点都当作了根节点,导致输出里出现了data2、data3这类本身是子节点的孤立路径条目。 - 递归关联方向颠倒:原递归部分把closure的
dst_id和CTE当前节点绑定,反向沿着父节点链路回溯,既搞反了路径拼接顺序,还把所有上游历史节点重复捞了出来,造成大量冗余结果。 - 偏离核心需求:没有识别真正的根节点(即没有任何父节点指向的节点),没有做到“从根出发遍历所有可达路径”的逻辑。
可直接运行的修正查询
;WITH hierarchy_cte AS ( -- 锚点:定位全局根节点(不存在上游父节点关联的节点) SELECT d.id, d.name, CAST(d.name AS VARCHAR(1000)) AS path, 0 AS pathDepth FROM data d WHERE NOT EXISTS ( SELECT 1 FROM closure c WHERE c.dst_id = d.id AND c.depth > 0 ) UNION ALL -- 递归:沿直接父子关系向下遍历,自动覆盖多父节点的所有分支 SELECT child_data.id, child_data.name, CAST(cte.path + ' / ' + child_data.name AS VARCHAR(1000)), cte.pathDepth + 1 FROM hierarchy_cte cte INNER JOIN closure c ON cte.id = c.src_id AND c.depth = 1 -- 仅匹配直接邻接的父子关联,不跨层级跳步 INNER JOIN data child_data ON c.dst_id = child_data.id ) SELECT * FROM hierarchy_cte ORDER BY pathDepth, id
输出匹配说明
执行后结果和预期格式完全对齐:
- 初始锚点仅识别出data1为唯一根节点,无其他孤立路径起点
- 递归过程自然覆盖多父节点的所有分支:比如data5同时关联data2、data4两个父节点,会生成
data1 / data2 / data5、data1 / data3 / data4 / data5两条独立路径 - 递归逻辑只沿直接关联向下延伸,遇到没有下游子节点的叶子节点(如data6)时自动终止,无冗余条目。
内容的提问来源于stack exchange,提问作者madibat
相关产品推荐
相关产品推荐

