我正在寻找一种方法,以基于任何节点ID来查询整个树结构(包括顶级父节点,到最后一个子级末尾)-无论如何,都是基于顶级父节点,内部的任何节点或非常底层的节点进行查询孩子。
即与以下人员一起用餐:
|--------------|
|ID | ParentID|
|--------------|
|229 | NULL |
|230 | 229 |
|231 | 229 |
|232 | 229 |
|233 | 229 |
| |
|300 | NULL |
|301 | 300 |
|302 | 301 |
|303 | 302 |
|304 | 300 |
----------------
基于查询 229 , 230 , 231 , 232 或对于 233 ,结果应始终相同:
229
230
231
232
233
基于查询 300 或 301 或 302 或 303 或对于 304 ,结果应始终相同:
300
301
302
303
304
答案 0 :(得分:4)
您可以使用递归CTE将每个ID分配给其最终父对象。然后,您可以使用此信息从父级获取所有ID:
with t as (
select v.*
from (values (229, null), (230, 229), (231, 229), (232, 229), (233, 229),
(300, NULL), (301, 300), (302, 301), (303, 300 )
) v(id, parentid)
),
cte as (
select id as ultimate_parent_id, id as relatedid
from t
where parentid is null
union all
select cte.ultimate_parent_id, t.id
from cte join
t
on cte.relatedid = t.parentid
)
select relatedid
from cte
where ultimate_parent_id = (select ultimate_parent_id
from cte
where relatedid = 231
);
Here是db <>小提琴。
答案 1 :(得分:1)
您需要的是recursive common table expression (CTE)。
查询方法如下:
declare @Table table(ID int, ParentID int)
insert into @Table(ID, ParentID) values
(229, NULL),
(230, 229 ),
(231, 229 ),
(232, 229 ),
(233, 229 ),
(300, NULL),
(301, 300 ),
(302, 301 ),
(303, 300 )
declare @LookingForId int = 300 --229
; with cte as (
select ID from @Table where ID = @LookingForId
union all
select t.ID from @Table t inner join cte on cte.ID = t.ParentID
)
select * from cte
公用表表达式就像临时视图,仅在查询中存在。递归CTE是在自己体内引用自己的CTE。您可以使用此技术遍历表中的父子层次结构。
答案 2 :(得分:1)
我认为您需要这样的东西:
SELECT Id
FROM TableName AS T
WHERE ISNULL(ParentId,Id) IN
(
SELECT ISNULL(ParentId,Id)
FROM TableName WHERE Id=229
)
ORDER BY T.Id