考虑下表
+--------+-------+--+
| Parent | Child | |
+--------+-------+--+
| 1 | 2 | |
| 10 | 13 | |
| 2 | 3 | |
| 3 | 4 | |
| 13 | 14 | |
| 4 | 5 | |
| 15 | 16 | |
| 5 | 1 | |
+--------+-------+--+
在此表中,我遵循父子的层次结构。从这张表我想得到一个结果如下表
+--------+-------+--+
| Parent | Child | |
+--------+-------+--+
| 1 | 2 | |
| 2 | 3 | |
| 3 | 4 | |
| 4 | 5 | |
| 5 | 1 | |
+--------+-------+--+
我希望在代码(1-2-3-4-5-1)中获得层次结构。目前我正在询问每个孩子的父母(有时,孩子可以是任何以前的父母,如5-1 )。对于长层次结构,它将执行许多查询。我怎样才能提高效率呢?
答案 0 :(得分:4)
;with cte(parent,child) as (
select parent, child
from sometable
where parent = 1 --- seed
UNION ALL
select t.parent, t.child
from sometable t
join cte on cte.child = t.parent
)
select *
from cte;
为避免无限循环,您必须存储遍历的ID列表:
;with cte(parent,child,traversed) as (
select parent, child, ',' + right(parent,10) + ','
from sometable
where parent = 1 --- seed
UNION ALL
select t.parent, t.child, cte.traversed + right(t.parent,10) + ','
from sometable t
join cte on cte.child = t.parent
where not cte.traversed like ',%' + t.parent + '%,'
)
select parent, child
from cte;
但由于必须进行LIKE检查,因此它不能快速地运行。
答案 1 :(得分:2)
请尝试:
DECLARE @table as TABLE(Parent int, Child int)
insert into @table values
(1, 2),
(10, 13),
(2, 3),
(3, 4),
(13, 14),
(4, 5),
(5, 1)
select * from @table
declare @ParentID int
set @ParentID=1
;WITH T(Parent, Child)AS
(
SELECT Parent, Child from @table where Parent=@ParentID
UNION ALL
SELECT T1.Parent, T1.Child FROM @table T1 INNER JOIN T ON T1.Parent=T.Child
WHERE T.Child<>@ParentID
)
select * from T
order by Parent
答案 2 :(得分:-1)
本手册涵盖:http://msdn.microsoft.com/en-us/library/ms186243(v=sql.105).aspx 所以不应该习惯于在手册中提出已经有好答案的问题。