得到 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
给定开头或中间或结尾的 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