我有一个表,我将从第三方Web服务中搜索几百个服务。这些服务有几百万个符号,我也是。
层次结构本质上就是这个;
root
|_service1
| |_service1/sub1*
| |_service1/sub2
| |_service1/sub3
| |_service1/sub4
| | |_service1/sub4/sub1
| | |_**service1/sub4/sub1/leaf1**
| |
| |_service1/sub5
|
|_service2
|_service2/sub1
|_service2/sub2
|_service2/sub3
所以我想要实现的是 - 给一个叶子的Id,我想在树上工作直到我发现分支isActive为真然后返回该值。
在此示例中,我想查找叶/service1/sub4/sub1/leaf1
的有效服务,在本例中为service1/sub1
到目前为止,我一直在使用Common Table Expression从上到下工作,并在该分支下的叶子上设置一个额外的ActiveServiceId列;数以百万计的符号变成了一个漫长的过程。
我只使用了一小部分符号(虽然我不知道哪些符号,但我需要它们)所以查询时已知的叶子ID只有几百个。 / p>
我创建了一个SQLFiddle来反映这个层次,以帮助任何可能提供帮助的人
更新进一步解释当前的方法。如果我决定将service1
作为新的活动服务 - 每个子分支中service1下的叶子需要冒泡到service1,我将重置所有子分支,因此它们都没有被标记为活动
答案 0 :(得分:1)
您可能会发现使用嵌套集存储此数据很有用:
http://en.wikipedia.org/wiki/Nested_set_model
我之前使用过这种方法将树数据存储在数据库中,发现它可以查询属于父级等所有节点的数据。
使用存储在嵌套集中的数据,您的问题的解决方案如下:
SELECT s.ID
FROM TreeTable s
WHERE s.L = (SELECT Max(t.L)
FROM TreeTable t, TreeTable LeafNode
WHERE t.isActive = true
AND t.L < LeafNode.L
AND t.R > LeafNode.R
AND LeafNode.ID = ?)
答案 1 :(得分:0)
如果您将完整路径存储为每个节点的字符串,则可以执行以下操作:
SELECT r.ID
FROM TreeTable r, TreeTable rs
WHERE rs.ID = ?
AND r.Path = Left(rs.path,Len(r.Path))
AND Len(r.Path) = (SELECT Max(Len(t.Path))
FROM TreeTable t, TreeTable s
WHERE s.ID = ?
AND t.Path = Left(s.path,Len(t.Path))
AND t.isActive = true)
好吧,它不漂亮,我欢迎任何使它更整洁的建议 - 但它应该有用。