Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL中的递归选择_Sql_Sql Server 2008_Recursive Query - Fatal编程技术网

SQL中的递归选择

SQL中的递归选择,sql,sql-server-2008,recursive-query,Sql,Sql Server 2008,Recursive Query,我有个问题,我就是想不起来。我知道我想要什么,只是无法在屏幕上显示出来。 我的桌子是这样的: Id, PK UniqueIdentifier, NotNull Name, nvarchar(255), NotNull ParentId, UniqueIdentifier, Null -1 -> -2 -> -3 -> -5 -4 ParentId具有FK to Id 我想要完成的是在我传入的id下面得到一个所有id的平面列表 例如: 1 TestN

我有个问题,我就是想不起来。我知道我想要什么,只是无法在屏幕上显示出来。 我的桌子是这样的:

Id, PK UniqueIdentifier, NotNull
Name, nvarchar(255), NotNull
ParentId, UniqueIdentifier, Null
-1
  -> -2
       -> -3
  -> -5
-4
ParentId具有FK to Id

我想要完成的是在我传入的id下面得到一个所有id的平面列表

例如:

1   TestName1    NULL
2   TestName2    1
3   TestName3    2
4   TestName4    NULL
5   TestName5    1
这棵树看起来像这样:

Id, PK UniqueIdentifier, NotNull
Name, nvarchar(255), NotNull
ParentId, UniqueIdentifier, Null
-1
  -> -2
       -> -3
  -> -5
-4
如果我现在要求4,我只会得到4,但如果我要求1,我会得到1,2,3和5。 如果我要2,我会得到2和3,依此类推


有没有人能给我指出正确的方向。我的大脑已经崩溃了,所以我感谢所有能得到的帮助

这是一篇关于这个问题的好文章。它从数据的开始一直到查询设计


此外,您还可以使用。

我猜实现您要查找的内容的最简单方法是使用公共表表达式编写递归查询:

试试这个:

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

下面是一个工作示例:

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
上进行筛选,其中包含要查询的树的开头

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

值得一提的是,您链接到的第一篇文章实际上使用了公共表表达式进行递归查询(尽管它没有出现并提到这一事实)。这将递归整个树,然后过滤想要的记录。从所需节点开始,然后向下递归不是“更好”吗?@Dems:优化器将把where子句移动到CTE中,因此它将按照您的建议执行。将起始条件移到递归机制之外似乎更清楚。抱歉,误读了它,这确实会在树上递归,因此WHERE子句确实可以防止计算不成功。这是我的方法,从搜索的节点递归到树下。这非常有效!似乎很快,完成了我想要的。非常感谢你的帮助!终于我又有了收获:)@Dems+1。向下递归是我想要的方式!:)工作完美。谢谢@Mikael。