获取层次结构数据直到最后 child - SQL 服务器
Get Hierarchy data until last child - SQL Server
我有这个 table 结构。我只想创建一个分层数据查询,直到最后 child,不再引用 parent。
Table结构:
ParentId ChildId
-------------------
NULL 6000101
6000101 6000102
6000101 6000106
6000101 6000107
6000102 6000103
6000102 6000104
6000102 6000105
6000103 6000101
6000104 6000101
6000105 6000101
6000106 6000101
6000106 6000102
6000107 6000102
6000107 6000105
Current data structure image
所需的结构或结果集:
ParentId ChildId
---------------------
NULL 6000101
6000101 6000102
6000101 6000106
6000101 6000107
6000102 6000103
6000102 6000104
6000102 6000105
Desired result Image
有人可以帮忙吗?
通常,在查询层次结构时会使用递归通用 table 表达式,但由于数据中存在循环引用,因此需要使用循环。
假设您的来源 table 被称为 "MyTable"。您需要创建一个 table(临时或其他)来保存清理后的层次结构:
create table MyHierarchy (
ParentId int null
,ChildId int not null
,[Level] int not null
);
然后您将输入根父记录并循环直到到达循环引用:
-- insert root parent record
insert into MyHierarchy
select
*
,0 as [Level]
from
MyTable
where
ParentId is null;
-- loop until you reach a circular reference
while @@ROWCOUNT > 0
begin
insert into MyHierarchy
select
MyTable.*
,MyHierarchy.[Level] + 1 as [Level]
from
MyTable
inner join
MyHierarchy on MyTable.ParentId = MyHierarchy.ChildId
where
MyTable.ChildId not in (select ChildId from MyHierarchy)
end
这让你几乎一路走来。您有一条记录 (ChildId = 6000105
) 引用了多个父项。偏向于较低级别,您现在可以使用带有 cte 的 row_number()
函数来获得唯一关系。
with cte as (
select
MyHierarchy.*
,ROW_NUMBER() OVER(PARTITION BY MyHierarchy.ChildId ORDER BY parent.[Level], MyHierarchy.parentId) as RowNumber
from
MyHierarchy
left join
MyHierarchy parent on MyHierarchy.ParentId = parent.ChildId
)
select
*
from
cte
where
RowNumber = 1
order by
ParentId
,ChildId
我有这个 table 结构。我只想创建一个分层数据查询,直到最后 child,不再引用 parent。
Table结构:
ParentId ChildId
-------------------
NULL 6000101
6000101 6000102
6000101 6000106
6000101 6000107
6000102 6000103
6000102 6000104
6000102 6000105
6000103 6000101
6000104 6000101
6000105 6000101
6000106 6000101
6000106 6000102
6000107 6000102
6000107 6000105
Current data structure image
所需的结构或结果集:
ParentId ChildId
---------------------
NULL 6000101
6000101 6000102
6000101 6000106
6000101 6000107
6000102 6000103
6000102 6000104
6000102 6000105
Desired result Image
有人可以帮忙吗?
通常,在查询层次结构时会使用递归通用 table 表达式,但由于数据中存在循环引用,因此需要使用循环。
假设您的来源 table 被称为 "MyTable"。您需要创建一个 table(临时或其他)来保存清理后的层次结构:
create table MyHierarchy (
ParentId int null
,ChildId int not null
,[Level] int not null
);
然后您将输入根父记录并循环直到到达循环引用:
-- insert root parent record
insert into MyHierarchy
select
*
,0 as [Level]
from
MyTable
where
ParentId is null;
-- loop until you reach a circular reference
while @@ROWCOUNT > 0
begin
insert into MyHierarchy
select
MyTable.*
,MyHierarchy.[Level] + 1 as [Level]
from
MyTable
inner join
MyHierarchy on MyTable.ParentId = MyHierarchy.ChildId
where
MyTable.ChildId not in (select ChildId from MyHierarchy)
end
这让你几乎一路走来。您有一条记录 (ChildId = 6000105
) 引用了多个父项。偏向于较低级别,您现在可以使用带有 cte 的 row_number()
函数来获得唯一关系。
with cte as (
select
MyHierarchy.*
,ROW_NUMBER() OVER(PARTITION BY MyHierarchy.ChildId ORDER BY parent.[Level], MyHierarchy.parentId) as RowNumber
from
MyHierarchy
left join
MyHierarchy parent on MyHierarchy.ParentId = parent.ChildId
)
select
*
from
cte
where
RowNumber = 1
order by
ParentId
,ChildId