查找多父层次结构的深度 - SQL

发布于 2024-12-12 19:42:57 字数 567 浏览 0 评论 0原文

我有一个包含两列的表:母亲 - 节点 该表构成了层次结构的基础。母亲指的是节点。 每个节点可以有多个母亲,每个母亲可以有多个孩子。这是通过多行来完成的。 如果 mother = NULL,则该节点是顶级节点。可以有多个顶级节点,一个节点既可以是顶级节点,也可以是另一个节点的子节点。 例如:

INSERT INTO MYTABLE VALUES(NULL, 2)
INSERT INTO MYTABLE VALUES(1, 2)

我现在正在构建一个程序,需要知道层次结构的最大深度。假设节点 E 是节点 D 的子节点,而节点 D 又是节点 C 的子节点。 节点 C 是顶级节点,也是节点 B 的子节点,节点 B 是节点 A 的子节点 节点A只是顶级节点。 如果我们说节点 A 的深度 = 0。那么在这种情况下,节点 E 的深度应该是 4。

有谁知道我如何构建一个可以为我找到这个深度的语句? 它必须找到表中每个节点的最大深度,然后返回这些节点的最大值。

谢谢!

顺便说一句,使用 SQL Server 2008。

编辑:

感兴趣的只是表的绝对最大深度。不是单个节点的深度。

I have a table with two columns: mother - node
This table forms the base of a hierarchy. A mother refers to a node.
Every node can have multiple mothers, and every mother can have multiple childs. This is accomplished by multiple rows.
If mother = NULL, then the node is a top level node. There can be several top-level nodes, and a node can be both a top-level node AND a child of another node.
e.g:

INSERT INTO MYTABLE VALUES(NULL, 2)
INSERT INTO MYTABLE VALUES(1, 2)

Im now building a procedure that will need to know the maximum depth of the hierarchy. Lets say node E is a child of node D who is a child of node C.
Node C is a top level node, and also a child of node B who is a child of node A
Node A is only a top level node.
If we say node A has a depth = 0. Then in this case the depth of node E should be 4.

Does anyone have a clue to how i could build a statement that would find this depth for me?
It would have to find the maximum depth of every node in the table and then return the max value of those.

Thanks!

Using SQL Server 2008 btw.

EDIT:

It is ONLY the absolute maximum depth of the table that is of interest. Not the depth of individual nodes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

街角迷惘 2024-12-19 19:42:57

试试这个,它会找到层次结构的所有底层

declare @mytable table(id int, parent_id int)

INSERT INTO @MYTABLE VALUES(1, NULL) 
INSERT INTO @MYTABLE VALUES(2, 1) 
INSERT INTO @MYTABLE VALUES(3, 1) --*
INSERT INTO @MYTABLE VALUES(4, 2) 
INSERT INTO @MYTABLE VALUES(5, 4) --*

;with a as
(
    select 
       id, 
       parent_id, 
       1 lvl 
    from @mytable 
    where parent_id is null
    union all
    select 
        b.id, 
        b.parent_id, 
        lvl+1 
    from @mytable b 
        join a on a.id = b.parent_id
)
select 
    a.id, 
    a.parent_id, 
    a.lvl 
from a
    left join a b on a.id = b.parent_id
where b.id is null
option (maxrecursion 0)

Try this, it will find all the bottom levels of the hierarchy

declare @mytable table(id int, parent_id int)

INSERT INTO @MYTABLE VALUES(1, NULL) 
INSERT INTO @MYTABLE VALUES(2, 1) 
INSERT INTO @MYTABLE VALUES(3, 1) --*
INSERT INTO @MYTABLE VALUES(4, 2) 
INSERT INTO @MYTABLE VALUES(5, 4) --*

;with a as
(
    select 
       id, 
       parent_id, 
       1 lvl 
    from @mytable 
    where parent_id is null
    union all
    select 
        b.id, 
        b.parent_id, 
        lvl+1 
    from @mytable b 
        join a on a.id = b.parent_id
)
select 
    a.id, 
    a.parent_id, 
    a.lvl 
from a
    left join a b on a.id = b.parent_id
where b.id is null
option (maxrecursion 0)
子栖 2024-12-19 19:42:57

好的。我找到了解决方案。

首先,我创建了一个带有两个额外列的临时表:

    CREATE TABLE #ParentChildTempTable
(
    Node NVARCHAR(50),
    Parent NVARCHAR(50),
    Depth TINYINT,
    Measure_Depth BIT
)

然后我将 true 顶级节点的深度设置为 0。False 顶级节点将 Measure_Depth 设置为 0。

    UPDATE #ParentChildTempTable SET Depth = 0 WHERE Parent IS NULL AND node not in 
(select Node from #ParentChildTempTable temp2 where temp2.Parent is not null)

UPDATE #ParentChildTempTable SET Measure_Depth = 0 WHERE Parent IS NULL AND node in 
(select Node from #ParentChildTempTable temp2 where temp2.Parent is not null)

然后我从顶层向下循环直到每个节点都有一个深度(预计假顶级别)

    WHILE EXISTS (SELECT * FROM #ParentChildTempTable WHERE Depth IS NULL AND Measure_Depth IS NULL) 
    UPDATE T SET T.Depth = P.Depth + 1
    FROM #ParentChildTempTable AS T 
    INNER JOIN #ParentChildTempTable AS P ON (T.Parent=P.Node) 
    WHERE P.Depth>=0 
    AND T.Depth IS NULL

瞧!找到最大深度:

DECLARE @MaxDepth INT = (SELECT MAX(Depth) FROM #ParentChildTempTable)

Ok. I found a solution.

First i created a temp-table with two extra columns:

    CREATE TABLE #ParentChildTempTable
(
    Node NVARCHAR(50),
    Parent NVARCHAR(50),
    Depth TINYINT,
    Measure_Depth BIT
)

I'm then setting the depth of true-top-level nodes to 0. False top-level nodes will have Measure_Depth set to 0.

    UPDATE #ParentChildTempTable SET Depth = 0 WHERE Parent IS NULL AND node not in 
(select Node from #ParentChildTempTable temp2 where temp2.Parent is not null)

UPDATE #ParentChildTempTable SET Measure_Depth = 0 WHERE Parent IS NULL AND node in 
(select Node from #ParentChildTempTable temp2 where temp2.Parent is not null)

I then loop down from the top-level until every node has a depth (expect the false-top level)

    WHILE EXISTS (SELECT * FROM #ParentChildTempTable WHERE Depth IS NULL AND Measure_Depth IS NULL) 
    UPDATE T SET T.Depth = P.Depth + 1
    FROM #ParentChildTempTable AS T 
    INNER JOIN #ParentChildTempTable AS P ON (T.Parent=P.Node) 
    WHERE P.Depth>=0 
    AND T.Depth IS NULL

And voila! Max depth is found:

DECLARE @MaxDepth INT = (SELECT MAX(Depth) FROM #ParentChildTempTable)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文