【问题标题】:Get Hierarchy data until last child - SQL Server获取直到最后一个孩子的层次结构数据 - SQL Server
【发布时间】:2018-08-11 04:28:20
【问题描述】:

我有这个表结构。我想为分层数据创建一个查询,直到最后一个子节点,不再引用父节点。

表结构:

    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

有人可以帮忙吗?

【问题讨论】:

  • 这里的大多数人想要格式化文本,而不是图像(或图像链接)。
  • 你好,真的很抱歉,我试过格式化但是不行,我应该用html标签格式化吗?
  • 编辑时,将数据写入适当的列。每行先放 4 个 字符,然后再放一个空行。
  • 对不起,我没有让它正常工作,但想出了一个编辑过的。
  • 也可以高亮代码块并按下大括号按钮{}(或CTRL+K)

标签: sql sql-server join hierarchical-data


【解决方案1】:

通常,在查询层次结构时会使用递归公用表表达式,但由于数据中有循环引用,因此需要使用循环。

假设您的源表名为“MyTable”。您需要创建一个保存已清理层次结构的表(临时表或其他表):

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

【讨论】:

  • 你太棒了。这很好用。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2016-09-27
  • 1970-01-01
相关资源
最近更新 更多