一旦结果集包含某个值,就退出递归公用表表达式

时间:2010-10-21 15:35:42

标签: sql-server sql-server-2005 tsql common-table-expression recursive-query

鉴于下表:

create table TreeNode
(
  ID int not null primary key,
  ParentID int null foreign key references TreeNode (ID)
)

如何编写公共表表达式以从根开始(WHERE ParentID IS NULL)并遍历其后代,直到结果集包含某个目标节点(例如,WHERE ID = n)?很容易从目标节点开始并向上遍历到根,但这不会生成相同的结果集。具体而言,不包括与目标节点具有相同父节点的节点。

我的第一次尝试是:

with Tree as
(
  select
    ID,
    ParentID
  from
    TreeNode
  where
    ParentID is null
  union all select
    a.ID,
    a.ParentID
  from
    TreeNode a
    inner join Tree b
      on b.ID = a.ParentID
  where
    not exists (select * from Tree where ID = @TargetID)
)

出现错误:Recursive member of a common table expression 'Tree' has multiple recursive references.

注意:我只对自上而下的遍历感兴趣。

1 个答案:

答案 0 :(得分:1)

更新2:

第三次尝试在两个方向上“遍历”树。

ParentIDsTarget建立所有root的CTE。然后,选择tree nodesID在短名单中显示的Parent

--
;
WITH    Tree
          AS ( SELECT   ID
                       ,ParentID
               FROM     TreeNode
               WHERE    [ID] = @targetId
               UNION ALL
               SELECT   a.ID
                       ,a.ParentID
               FROM     TreeNode a
                        INNER JOIN Tree b ON b.ParentID = a.ID
             )
    SELECT  *
    FROM    [dbo].[TreeNode] n
    WHERE  EXISTS (SELECT *
                   FROM [Tree] t
                   WHERE [t].[ID] = [n].[ID]
                         OR [t].[ID] = [n].[ParentID]
                  )