获取层次结构数据直到最后 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

http://sqlfiddle.com/#!18/7089d/3