【问题标题】:Exiting from recursive common table expression once the result set contains some value一旦结果集包含某个值,就退出递归公用表表达式
【发布时间】:2010-10-21 15:35:41
【问题描述】:

给定下表:

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.

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

【问题讨论】:

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


    【解决方案1】:

    更新 2:

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

    构建从Targetroot 的所有ParentIDs 的CTE。然后,从nodes 中选择IDParent 出现在短列表中的nodes

    --
    ;
    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]
                      )
    

    【讨论】:

    • 我认为我们不能假设树中较高的节点总是具有较低的 ID。
    • @Daniel,请注意。我已经更新了我的查询。它仍然适用于我的小样本集。
    • 问题具体是如何自顶向下遍历。我在 OP 中提到了自下而上的问题。
    • @Daniel,非常正确。我错过了。我已经对向下遍历进行了另一次试验。它以 UP-traversal 开始,然后返回并获取沿途属于的所有节点。
    • 最后一行不应该是:[t].[ParentID] = [n].[ID]
    猜你喜欢
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-30
    • 2012-09-15
    • 1970-01-01
    • 2011-10-05
    相关资源
    最近更新 更多