在SQL中递归选择

时间:2011-04-13 12:46:34

标签: sql sql-server-2008 recursive-query

我有一个问题,我无法理解。我知道我想要什么,只是简直无法在屏幕上看到它。 我所拥有的是一张如下表:

Id, PK UniqueIdentifier, NotNull
Name, nvarchar(255), NotNull
ParentId, UniqueIdentifier, Null

ParentId有一个FK到Id。

我想要完成的是获取我传入的ID下方所有ID的平面列表。

示例:

1   TestName1    NULL
2   TestName2    1
3   TestName3    2
4   TestName4    NULL
5   TestName5    1

树看起来像这样:

-1
  -> -2
       -> -3
  -> -5
-4

如果我现在要求4,我只会回来4,但如果我要求1,我会得到1分,2分,3分和5分。 如果我要求2,我会得到2和3,依此类推。

有没有人可以指出我正确的方向。我的大脑很油炸,所以我很感激能得到的所有帮助。

5 个答案:

答案 0 :(得分:15)

declare @T table(
  Id int primary key,
  Name nvarchar(255) not null,
  ParentId int)

insert into @T values
(1,   'TestName1',    NULL),
(2,   'TestName2',    1),
(3,   'TestName3',    2),
(4,   'TestName4',    NULL),
(5,   'TestName5',    1)

declare @Id int = 1

;with cte as
(  
  select T.*
  from @T as T
  where T.Id = @Id
  union all
  select T.*
  from @T as T
    inner join cte as C
      on T.ParentId = C.Id
)
select *
from cte      

结果

Id          Name                 ParentId
----------- -------------------- -----------
1           TestName1            NULL
2           TestName2            1
5           TestName5            1
3           TestName3            2

答案 1 :(得分:4)

这是一个有效的例子:

declare @t table (id int, name nvarchar(255), ParentID int)

insert @t values
(1,   'TestName1',    NULL),
(2,   'TestName2',    1   ),
(3,   'TestName3',    2   ),
(4,   'TestName4',    NULL),
(5,   'TestName5',    1   );

; with rec as
        (
        select  t.name
        ,       t.id as baseid
        ,       t.id
        ,       t.parentid
        from    @t t
        union all
        select  t.name
        ,       r.baseid
        ,       t.id
        ,       t.parentid
        from    rec r
        join    @t t
        on      t.ParentID = r.id
        )
select  *
from    rec
where   baseid = 1

您可以对baseid进行过滤,其中包含您要查询的树的开头。

答案 2 :(得分:0)

这是一篇关于Hierarchy ID models的好文章。它从数据的开头直到查询设计。

此外,您可以使用Recursive Query using a Common Table Expression

答案 3 :(得分:0)

我猜想完成你正在寻找的最简单方法是使用公用表表达式编写递归查询:

MSDN - Recursive Queries Using Common Table Expressions

答案 4 :(得分:0)

试试这个:

WITH RecQry AS
(
    SELECT *
      FROM MyTable
    UNION ALL
    SELECT a.*
      FROM MyTable a INNER JOIN RecQry b
        ON a.ParentID = b.Id
)
SELECT *
  FROM RecQry