如何从嵌套集中(不包括子树)中选择路径

时间:2018-08-11 01:11:23

标签: sql sqlite nested

我有一个SQLite数据库,其中包含带有红色和黑色节点的树(尽管不是红黑树)。树存储为嵌套集(https://en.wikipedia.org/wiki/Nested_set_model

Name TreeId Left Right IsBlack
A    1      1    8     1
B    1      2    7     0
C    1      3    6     1
D    1      4    5     1
A    2      1    10    1
B    2      2    5     0
C    2      6    9     1
D    2      3    4     1
D    2      7    8     1

TreeId = 2的B和C节点都指向D节点。所以D被写了两次。

这些树可能只包含黑色或红色节点

我想为指定节点选择不包含红色节点的所有路径。 e。从结果中排除红色节点及其所有子树

示例:

记录下来:

Name TreeId Left Right IsBlack
A    1      1    8     1

结果将是:

Name TreeId Left Right IsBlack
A    1      1    8     1

记录下来:

Name TreeId Left Right IsBlack
C    1      3    6     1

结果将是:

Name TreeId Left Right IsBlack
C    1      3    6     1
D    1      4    5     1

最后,记录下来:

Name TreeId Left Right IsBlack
A    2      1    10    1

结果将是:

Name TreeId Left Right IsBlack
A    2      1    10    1
C    2      6    9     1
D    2      7    8     1

为简单起见,我们假设存在另一个查询,该查询按其名称选择搜索节点的TreeId,Left和Right参数。

所以我想出了以下查询(针对节点A):

SELECT Nodes.* FROM Nodes
LEFT JOIN Nodes as n ON Nodes.[TreeId] = n.TreeId AND n.IsBlack = 0 AND Nodes.Left >= n.Left AND Nodes.Right <= n.Right
AND n.Left >= 1 AND n.Right <= 10
WHERE Nodes.TreeId = 2 AND Nodes.Left >= 1 AND Nodes.[Right] <= 10 AND n.Name IS NULL

该查询似乎可以正常运行,但是由于即使有索引也可以进行左联接,因此查询速度非常慢。

所以我在想,是否有一种方法可以根据SQLite来优化查询,避免左连接(例如,使用内部连接,联合等)

P.S。我无法更改数据的存储方式,但是可以修改数据库架构(添加新字段)。

P.P.S。我了解,我可以查询所有结果,然后在代码端对其进行过滤。另一种选择是在db中存储两种类型的树:一种具有红色和黑色节点,另一种仅具有黑色节点。但是,这两种解决方案都是不得已的方法。

预先感谢

1 个答案:

答案 0 :(得分:1)

好吧,我不知道它是否会更快-不能只显示几行数据,但这是使用递归CTE至少获得与示例相同的结果:< / p>

WITH RECURSIVE n AS
 (SELECT * FROM nodes WHERE name= ?1 AND treeid = ?2 AND isblack = 1
  UNION ALL
  SELECT n2.name, n2.treeid, n2.left, n2.right, n2.isblack
   FROM n
   JOIN nodes AS n2  
   ON     n2.treeid = n.treeid
      AND (n2.left = n.left + 1 OR n2.right = n.right - 1)
   WHERE n2.isblack = 1)
SELECT * FROM n ORDER BY name

您可能希望在nodes(isblack, treeid, name)上建立索引(并且不要忘记偶尔运行一次PRAGMA optimize。)绑定/替换?1?2以及针对特定查询运行的明显值。