代码之家  ›  专栏  ›  技术社区  ›  jamesh

如何在递归SQL查询中查找子树中的所有节点?

  •  5
  • jamesh  · 技术社区  · 16 年前

    我有一个表,它定义了节点之间的子-父关系:

    CREATE TABLE node (                           ' pseudo code alert
      id        INTEGER PRIMARY KEY,
      parentID  INTEGER, ' should be a valid id.
    )
    

    如果 parentID 总是指向一个有效的现有节点,然后这将自然地定义一个树结构。

    如果 帕伦特 NULL 然后我们可以假设节点是根节点。

    我将如何:

    1. 查找给定节点的所有减速节点?
    2. 查找给定节点下特定深度的所有节点?

    我希望将这些查询作为一个单独的SQL(我希望它必然是递归的)或两个相互递归的查询来完成。

    我在一个ODBC上下文中进行此操作,因此我不能依赖于任何特定于供应商的功能。

    编辑

    • 尚未编写表,因此添加额外的列/表是完全可以接受的。
    • 树可能会经常更新和添加;辅助数据结构/表/列是可能的,尽管需要保持最新。 如果你有什么魔法书可以帮你解答这个问题,我想知道。

    多谢。

    4 回复  |  直到 16 年前
        1
  •  4
  •   jamesh    16 年前

    This link 提供关于邻接列表模型(如问题中所述)和嵌套集模型的教程。它是作为mysql文档的一部分编写的。

    那篇文章没有讨论的是插入/删除时间和这两种方法的维护成本。例如:

    • 使用嵌套集模型动态生长的树似乎需要一些维护来维护嵌套(例如重新编号所有左、右集合编号)。
    • 删除邻接列表模型中的节点需要至少在另一行中进行更新。
        2
  •  2
  •   ChrisW    16 年前

    如果你有什么魔法书可以帮你解答这个问题,我想知道。

    Celko 用于Smarties的SQL中的树和层次结构

        3
  •  1
  •   Community CDub    7 年前

    本文前面介绍了一些方法:

    SQL - how to store and navigate hierarchies

        4
  •  1
  •   Bork Blatt    16 年前

    将根节点ID中的整个“路径”存储在单独的列中,同时确保在开始和结束时使用分隔符。例如,假设1是5的父级,它是17的父级,分隔符是破折号,您将在路径列中存储值1-5-17。

    现在要查找5的所有子级,只需选择路径包含-5的记录-

    两端的分隔符是必需的,因此在使用like时,您不必担心字段最左端或最右端的ID。

    至于深度问题,如果在表中添加一个表示当前嵌套深度的深度列,这也变得很容易。查找起始节点的深度,然后在其中添加x,其中x是要搜索的深度级别数,并筛选出深度大于该深度的记录。