如何查询树中两个节点之间的所有节点?

时间:2010-11-03 16:17:40

标签: sql hierarchical-data hierarchical-trees hierarchical-query transitive-closure-table

我有一个分层的数据库结构,例如为每行定义了IDPARENT_ID列,其中顶级行包含NULL PARENT_ID

我将此表中的所有关系扁平化为另一个表格,例如如果在祖父母,父母,孙子的单一等级中有三条记录,则会有3条记录:

**ANCESTOR, DESCENDANT**
grantparent, parent
grandparent, grandchild
parent, grandchild

不是执行分层查询来确定孙子孙女是祖父母的后代,而是可以简单地检查这个扁平化表格中是否存在(grandparent, grandchild)记录。

我的问题是,使用这个展平的表格,如何最有效地返回两个节点之间的所有记录。使用示例,以grandparentgrandchild作为参数,如何取回(grandparent, parent)记录。

我不想使用分层查询来解决这个问题...我想知道是否可以在没有任何连接的情况下执行此操作。

3 个答案:

答案 0 :(得分:2)

SELECT  *
FROM    mytable
WHERE   descendant = @descendant
        AND hops < 
        (
        SELECT  hops
        FROM    mytable
        WHERE   descendant = @descendant
                AND ancestor = @ancestor
        )

@ancestor不是@descendant的祖先时,这会自动处理。

(descendant, hops)上创建一个索引,以便快速工作。

答案 1 :(得分:1)

尝试:

select h1.descendant intermediate_node
from hierarchy h0 
join hierarchy h1 
  on h0.ancestor = h1.ancestor 
 and h0.hops > h1.hops  -- redundant condition, but may improve performance
join hierarchy h2
  on h1.ancestor = h2.ancestor 
 and h0.descendant = h2.descendant
where h0.ancestor = :ancestor and h0.descendant = :descendant

答案 2 :(得分:0)

SELECT
   distinct ancestor 
FROM 
   hierarchy 
WHERE descendant = :1 AND 
      ancestor IN (
                    SELECT 
                       distinct descendant 
                    FROM 
                       hierarchy WHERE ancestor = :2
                  )