我可以将此游标和while循环转换为基于集合的解决方案吗?

时间:2018-10-26 18:29:29

标签: sql sql-server tsql

我目前正在编写一个脚本,其中有一棵树以及一组已知的父节点(都不是根节点)和一组已知的子节点。对于每个子节点,我必须找到父节点之一的直接后代,该父节点也是该子节点的父节点。对于每个子节点,仅存在一个这样的值,但是每个子节点与其对应的目标之间可以有任意数量的节点。

我现在拥有的是一个游标,它遍历每个子节点,并使用while循环在树上向上移动,直到在父节点集中找到一个具有父节点的节点为止,这就是匹配项。我的问题是,是否可以在没有游标或while循环的情况下以基于集合的方式解决此问题?我不是sql专家,但是无法提出使用合并或联接执行此操作的方法。

1 个答案:

答案 0 :(得分:2)

在处理看似困难的树问题时,建立“祖先表”通常很有用。这不仅仅是SQL的事情,它还是处理层次结构时常用的工具。

祖先表包含各个节点之间的所有连接。因此,如果您有一个图,其根为A,B为A的子级,而C为B的子级,那么您的祖先表将包含从B到A的连接行,以及从C到B的连接行, 用于从C到A的连接行,然后是“根”行(从A到A,长度为零)(可选)。

一旦有了这样的表格,大多数问题就变得很容易阐述。例如,您的问题将变成一组相当简单的联接以执行以下操作:

  

在祖先中查找行R1(父级,子级,长度)的集合,其中R1.parent是KnownParent,路径长度为1 (这为您提供KnownParents的直接后代),并且然后在祖先中找到行R2(父级,子级)的集合,其中R2.parent = R1.child,而R2.child是KnownChilld

HABO提到,可以使用递归CTE来生成祖先表。有一个关于here

的现有stackoverflow答案

祖先表不是回答此问题的唯一方法,但是我建议使用一个祖先表,这是一件很有用的事情。当然,您不必坚持祖先,只需直接加入递归cte的输出即可。