嵌套树中“正确”值的目的是什么?

时间:2010-09-15 17:18:31

标签: sql tree nested

如果我正在寻找父母的嵌套节点,我会查询这样的孩子:

parent.left< child.left

但总是如此:

child.right< parent.right

那么为什么我发现的所有例子都在查询之间运行?

感谢, 马特

3 个答案:

答案 0 :(得分:2)

在嵌套集中,通过指定每个节点的左右边界来描述层次结构,并且所有后代节点都在这些边界内。假设您的层次结构看起来像

A
 - B
 - C
    - D
    - E
 - F
 - G
H
I
 - J

当每一行都添加到您的嵌套集中时,您最终会得到一个如下表格:

+----+--------+-----+-----+-----------+
| id | value  | lft | rgt | parent_id |
+----+--------+-----+-----+-----------+
|  1 | A      |   1 |  14 |      NULL |
|  2 | B      |   2 |   3 |         1 |
|  3 | C      |   4 |   9 |         1 |
|  4 | D      |   5 |   6 |         3 |
|  5 | E      |   7 |   8 |         3 |
|  6 | F      |  10 |  11 |         1 |
|  7 | G      |  12 |  13 |         1 |
|  8 | H      |  15 |  16 |      NULL |
|  9 | I      |  17 |  20 |      NULL |
| 10 | J      |  18 |  19 |         9 |
+----+--------+-----+-----+-----------+

或者以另一种方式看待它:

        -D- -E-
  -B- -----C----- --F-- --G--             --J--
---------------A---------------- --H-- -----I-----
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

如果要查询节点的所有后代(让我们说A),您可以这样查询:

SELECT *
FROM table AS node
JOIN table AS parent
  ON parent.id = 1
WHERE node.lft BETWEEN parent.lft AND parent.rgt -- BETWEEN 1 AND 14
ORDER BY lft

由于每个节点的左边界必须小于其右边界,因此您不需要检查节点的右边界,而只需搜索属于父边界的节点(因此只需要确定右边界)集合的结尾是)。例如,如果您尝试获取节点C的后代,并且只检查C的左边界,则查询将返回兄弟节点(F和{ {1}})和无关(GHI)到J

答案 1 :(得分:0)

我相信二元搜索树(BST)总是如此,不一定都是二叉树。

答案 2 :(得分:0)

如果您在谈论Nested Set Model,那么您就错了:parent.left < child.leftchild.right < parent.right

因此,您可以通过查询其左右ID之间的节点ID来获取节点的所有子节点。

请参阅this link中Celko的第二个查询:

SELECT P2.*
FROM Personnel AS P1, Personnel AS P2
WHERE P1.lft BETWEEN P2.lft AND P2.rgt
AND P2.emp = :myemployee;