Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server CTE从任意条目中提取整个树_Sql Server_Tree_Sql Server 2012_Common Table Expression - Fatal编程技术网

Sql server CTE从任意条目中提取整个树

Sql server CTE从任意条目中提取整个树,sql-server,tree,sql-server-2012,common-table-expression,Sql Server,Tree,Sql Server 2012,Common Table Expression,我正在尝试构建一个CTE,它将收回与数据库中给定的任意记录相关的所有记录 Create table Requests ( Id bigint, OriginalId bigint NULL, FollowupId bigint NULL ) insert into Requests VALUES (1, null, 3) insert into Requests VALUES (2, 1, 8) insert into Requests VALUES (3, 1, 4) inser

我正在尝试构建一个CTE,它将收回与数据库中给定的任意记录相关的所有记录

Create table Requests (
  Id bigint,
  OriginalId bigint NULL,
  FollowupId bigint NULL
)

insert into Requests VALUES (1, null, 3)
insert into Requests VALUES (2, 1, 8)
insert into Requests VALUES (3, 1, 4)
insert into Requests VALUES (4, 3, null)
insert into Requests VALUES (5, null, null)
insert into Requests VALUES (6, null, 7)
insert into Requests VALUES (7, 6, null)
insert into Requests VALUES (8, 2, null)
OriginalId
始终是以前记录的
Id
(或
null
FollowupId
指向最新的跟踪记录(反过来,它通过
OriginalId
返回),可能会被忽略,但如果有用的话,它就在那里

我可以使用下面的CTE轻松地提取给定记录的所有祖先或所有后代

;With TransactionList (Id, originalId, followupId, Steps)
AS
(
    Select Id, originalId, followupId, 0 as Steps from requests where Id = @startId
    union all
    select reqs.Id, reqs.originalId, reqs.followupId, Steps + 1 from requests reqs
    inner join TransactionList tl on tl.Id = reqs.originalId --or tl.originalId = reqs.Id
)
SELECT Id from TransactionList
然而,如果我同时使用where子句,我会遇到递归,达到递归极限,然后它就爆炸了。即使把这两个集合结合起来,我也不能得到整棵树——只有一根树枝

除了ID列表,我什么都不在乎。它们不需要排序,也不需要显示它们的关系或任何东西。不痛,但没必要。但我需要给定树中的每个
Id
,当它作为
@startId
传递时,将其向后拉

作为我想看到的示例,这是当
@startId
设置为任何值1-4或8时输出的结果:

1
2
3
4
8

对于6或7,我得到6和7。您只需创建2个CTE即可

第一个CTE将获取层次结构的根,第二个CTE将使用根ID获取根的子代

;WITH cteRoot AS (
    SELECT  *, 0 [Level]
    FROM    Requests
    WHERE   Id = @startId
    UNION ALL
    SELECT  r.*, [Level] + 1
    FROM    Requests r
            JOIN cteRoot cte ON r.Id = cte.OriginalID
),
cteDesc AS (
    SELECT  *
    FROM    cteRoot
    WHERE   OriginalId IS NULL
    UNION ALL
    SELECT  r.*, [Level] + 1
    FROM    Requests r
            JOIN cteDesc cte ON r.OriginalId = cte.Id  
)
SELECT * FROM cteDesc  

你在这里并不陌生。一些ddl和样本数据怎么样?sqlfiddle.com也许?@SeanLange-我无法让fiddle运行我的CTE。但我已经在问题中添加了数据和预期结果。对不起,我在问题的初始版本中不够清楚。将这两种方法结合起来,只会得到树从上到下的一个分支,但我需要所有分支。@Bobson我更新了查询,只得到根,然后从那里沿着层次结构往下走。太好了。谢谢回想起来,这似乎是显而易见的。