鉴于这样的树:
A----B---------C----D | | E----F G | H
我需要找到C和E(每个独特分支的两个最深的节点; A-C和A-E)
我们的数据库使用嵌套集模型以及邻接列表作为备份,以便在左右值不同步的情况下维护树结构。
我可以排除所有叶子节点(rgt = lft + 1) 和根节点(lft = 1) 这让我看到了B E C.你可以想象这是一个非常简化的例子,我们的一些树有超过100个节点。如何在数据中消除这种噪音?
以上示例的数据如果存储在我们的数据库中。
node | parent | lft | rgt | ------+--------+-----+-----+ 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|
感谢您的帮助!
答案 0 :(得分:0)
你是对的,第一步是通过它们的属性等于左+ 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
)
)