【发布时间】:2018-08-23 14:01:24
【问题描述】:
据我了解,如果您将一个部分定义为父级,另一个定义为子级,则任何多对多关系都是一种层次结构。
我有一种情况,我需要在多对多表中获取映射到自身的对象的子对象,但我很难为它编写递归 CTE。
例如,假设我有:
ParentId ChildId
======== =======
2 20
2 30
5 50
20 200
21 201
30 300
31 301
对于根级别,我使用的规则是它是一个根对象,如果它的 ID 不在第二列 (ChildId) 中,但这是有问题的,因为从上面的示例中可以看出,我可以根的多条记录(ID:2)
对于递归部分,无论我尝试什么,要么得到无限递归,要么递归根本不起作用。
所以我完全被卡住了。
更新 只是添加更多说明。我正在构建一个存储过程,该过程在 parentId 中传递,并且内部具有递归 CTE。我想要得到的输出是,对于传入 2 的 parentId,使用上面的示例,我想:
ParentId ChildId Level
======== ======= =====
2 20 0
2 30 0
20 200 1
30 300 1
这是我的一些代码:
alter procedure [dbo].[FindChildren]
@Id bigint
as
begin
;with DocumentHierarchyCTE (ParentId, ChildId, LevelNumber)
as
(
select
th.ParentDocumentId as ParentId,
th.ChildDocumentId as ChildId,
0 as LevelNumber
from dbo.DocumentHierarchy th
where
th.ParentDocumentId = @Id
and not exists(select 1 from dbo.DocumentHierarchy tz where tz.ChildDocumentId = th.ParentDocumentId )
union all
???
)
select *
from DocumentHierarchyCTE d
option (maxrecursion 0)
end
go
【问题讨论】:
-
您好,欢迎来到 SO。你说递归根本不起作用。这意味着什么?你能分享你试过的吗?此外,您的示例数据有点混乱(而且似乎不完整)。这将是一个很好的起点。 spaghettidba.com/2015/04/24/…
-
为什么样本数据令人困惑? 2个有孩子(20,30),20个有孩子(200),30个有孩子(300)。当我说递归不起作用时,我的意思是递归只返回根记录。
-
你希望你的输出是什么样的?
-
嗯...200 和 300 在哪里?你怎么知道 2 是你的根?递归 cte 的想法是从根开始并找到所有孩子。您无法在这些数据中知道根是什么。再说一次,你尝试了什么?我的意思是分享您尝试但不起作用的查询。给我们一些可以合作的东西。
-
@RobertSievers:我更新了我的答案
标签: sql-server recursion many-to-many recursive-cte