得到 parents 和 children 给定递归 SQL 中的一个段

Get parents and children given a segment in a recursion SQL

给定开头或中间或结尾的 ID,我想查找它们之间链接的所有行。

通过这个我递归地找到了 child 个元素

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

insert into @T values
(1,   'A',    NULL),
(2,   'B',    1),
(3,   'C',    2),
(4,   'D',    NULL),
(5,   'E',    1)

declare @Id int = 2

;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 等于 2,我将得到 2 和 3。但我也想检索 parent,在本例中为 1。

我想要这个:

如果 id = 1

1 A NULL
2 B 1
3 C 2
5 E 1

如果 id = 2

1 A NULL
2 B 1
3 C 2
5 E 1

如果 id = 3

1 A NULL
2 B 1
3 C 2
5 E 1

如果 id = 4

4 D NULL

如果 ID = 5

1 A NULL
2 B 1
3 C 2
5 E 1

我该如何解决这个问题?

好的!我找到你了:

我创建了一个单独的家庭进行测试。

您需要做的第一件事是创建查询以查找所选 ID 的最早祖先。这是下面的第一个 CTE。那你指定那个,我叫它@Eve然后找夏娃,夏娃的所有children

Here is the example 你可以玩

  create table UserType (
  Id int,
   name nvarchar(255),
  parentid int)

insert into UserType values
(1,  'A',    NULL),
(2,  'B',  1),
(3,  'C',   2),
(4,  'D',    NULL),
(5,  'E',   1),
(6,  'F',   NULL),
(7,  'G',      6),
(8,  'H',     7);

DECLARE @eve BIGINT;  --ancestor
DECLARE @id BIGINT;
SET @id = 8;  --This is where you choose

WITH tblParent AS  --CTE for oldest ancestor
(
    SELECT *
        FROM UserType WHERE Id = @id
    UNION ALL
    SELECT UserType.*
        FROM UserType  JOIN tblParent  ON UserType.Id = tblParent.ParentId
)
select
@eve = (select top 1 id from tblParent order by id);

WITH tblChild AS  --CTE for all @eve and all children
(
    SELECT *
        FROM UserType WHERE id = @eve
    UNION ALL
    SELECT UserType.* FROM UserType  JOIN tblChild  ON UserType.ParentId = tblChild.Id
)
SELECT * FROM tblChild
order by id


OPTION(MAXRECURSION 32767)

Props to CodeProject 这很有帮助。

尝试这样的事情。

declare  @tbl table( --test table var
Id int,
name nvarchar(255),
parentid int)

insert into @tbl values -- test data
(1,  'A',    NULL),
(2,  'B',  1),
(3,  'C',   2),
(4,  'D',    NULL),
(5,  'E',   1),
(6,  'F',   NULL),
(7,  'G',      6),
(8,  'H',     7);

declare @id int = 7

;with parents as (
select id,name,parentid, 0 lvl
from @tbl 
where id=@id
union all
select t.id,t.name,t.parentid,  lvl-1
from @tbl t
inner join parents p on t.Id=p.parentid --up the tree
)
,children as (
select id,name,parentid, 0 lvl
from @tbl 
where id=@id --select single record
union all
select t.id,t.name,t.parentid,  lvl+1
from @tbl t
inner join children c on c.Id=t.parentid -- down the tree
)
select * from parents
union --combine results
select * from children
order by lvl