【问题标题】:SQL - nested set model - how do I find the deepest parents (not leaf nodes) of each branchSQL - 嵌套集模型 - 我如何找到每个分支的最深父节点(不是叶节点)
【发布时间】:2011-02-10 18:20:52
【问题描述】:

给定一棵这样的树:

A B C D | | E----F G | H

我需要找到 C 和 E(每个唯一分支的两个最深的节点;A-C 和 A-E)

我们的数据库使用嵌套集模型以及邻接表作为备份来维护树结构,以防左右值不同步。

我可以排除所有叶节点( rgt = lft + 1 ) 和根节点( lft = 1 ) 这给我留下了 B E C。你可以想象这是一个大大简化的例子,我们的一些树有超过 100 个节点。如何消除数据中的这种噪音?

如果数据存储在我们的数据库中,这是上面示例的数据。

节点 |家长 |半边天 | rgt | ------+--------+-----+-----+ 一个 |空 | 1| 16| 乙|一个 | 2| 15| E |乙| 3| 8| F | E | 4| 5| H | E | 6| 7| C |乙| 9| 14| D | C | 10| 11| 克| C | 12| 13|

感谢您的帮助!

【问题讨论】:

    标签: nested-sets


    【解决方案1】:

    你是对的,第一步是通过它们的属性 right 等于 left + 1 来识别叶节点。下一步是找到这些叶节点的所有父节点:它们的左值小于叶的左值,并且正好比叶子大。最后一步是排除所有父节点,但左值最大(即最接近叶节点)的父节点除外。

    T-SQL 中的一个示例,其中 l 是叶节点,p1 是我们要查找的直接父节点,p2 用于清除所有非直接父节点。

    首先建立一个包含您的示例数据的测试表:

    if object_id('tempdb..#nsm') is not null
        drop table #nsm;
    
    select v.node, v.parent, v.lft, v.rgt
    into #nsm
    from (
        values 
           ('A'  ,     NULL,     1,   16),
           ('B'  ,    'A'   ,    2,   15),
           ('E'  ,    'B'   ,    3,    8),
           ('F'  ,    'E'   ,    4,    5),
           ('H'  ,    'E'   ,    6,    7),
           ('C'  ,    'B'   ,    9,   14),
           ('D'  ,    'C'   ,   10,   11),
           ('G'  ,    'C'   ,   12,   13)
       ) v (node, parent, lft, rgt)
    

    这是检索您请求的节点 C 和 E 的查询:

    select p1.node, p1.parent, p1.lft, p1.rgt
    from #nsm p1
    where exists (
                select *
                from #nsm l
                where l.rgt = l.lft + 1
                    and p1.lft < l.lft
                    and p1.rgt > l.rgt
                    and not exists (
                            select *
                            from #nsm p2
                            where p2.lft < l.lft
                                and p2.rgt > l.rgt
                                and p2.lft > p1.lft
                        )
            )
    

    【讨论】:

      猜你喜欢
      • 2010-12-08
      • 1970-01-01
      • 2022-11-16
      • 2013-10-07
      • 2017-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多