1

考虑下表

+--------+-------+--+
| 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)。对于长层次结构,它将执行许多查询。我怎样才能使它更有效率?

4

3 回答 3

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 检查。

于 2013-04-24T10:47:12.293 回答
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
于 2013-04-24T10:49:11.950 回答
-1

该手册涵盖:http: //msdn.microsoft.com/en-us/library/ms186243 (v=sql.105).aspx 所以真的不应该习惯于提出手册中已经有很好答案的问题.

于 2013-04-24T10:50:19.103 回答