具有停止条件

时间:2018-02-23 19:03:26

标签: mysql sql data-structures tree mariadb

我在表中使用嵌套集树结构。概念描述为here

示例数据如下所示:

+----+-----------+------+-------+-----------------+
| id | parent_id | left | right | stop_descending |
+----+-----------+------+-------+-----------------+
|  1 |      NULL |    1 |    10 |               0 |
|  2 |         1 |    2 |     3 |               0 |
|  3 |         1 |    4 |     9 |               1 |
|  4 |         3 |    5 |     6 |               0 |
|  5 |         3 |    7 |     8 |               0 |
+----+-----------+------+-------+-----------------+

获取整棵树非常简单:

SELECT t0.*
FROM nested_set AS t0
LEFT JOIN nested_set AS t1 ON t0.left BETWEEN t1.left AND t1.right
WHERE t1.parent_id IS NULL
ORDER BY t0.left;

但是,我想得到父节点没有stop_ descending标志的所有节点。结果应包括节点1,2,3。应排除节点4,5,因为它们的父节点具有stop_ descending标志。如果节点4和5有子节点,则也应排除这些节点。一旦is_leaf值等于1,递归应该停止。

我尝试了许多不同的方法但从未得到正确的结果。我正在MariaDB 10.1.26中运行查询。也许有更好的解决方案将CTE纳入更高版本。

1 个答案:

答案 0 :(得分:1)

您执行另一个自联接以检查该叶是否是具有stop_decending = 1

的节点的一部分

<强> SQL DEMO

SELECT t0.*, t1.*, t3.*
FROM nested_set AS t0
LEFT JOIN nested_set AS t1 
  ON t0.left BETWEEN t1.left AND t1.right

LEFT JOIN nested_set as t3
  ON t0.id BETWEEN t3.left AND t3.right
 AND t3.stop_descending  = 1

WHERE t1.parent_id IS NULL
  AND t3.id IS NULL
ORDER BY t0.left;

<强>输出

| id | parent_id | left | right | stop_descending | id | parent_id | left | right | stop_descending |     id | parent_id |   left |  right | stop_descending |
|----|-----------|------|-------|-----------------|----|-----------|------|-------|-----------------|--------|-----------|--------|--------|-----------------|
|  1 |    (null) |    1 |    10 |               0 |  1 |    (null) |    1 |    10 |               0 | (null) |    (null) | (null) | (null) |          (null) |
|  2 |         1 |    2 |     3 |               0 |  1 |    (null) |    1 |    10 |               0 | (null) |    (null) | (null) | (null) |          (null) |
|  3 |         1 |    4 |     9 |               1 |  1 |    (null) |    1 |    10 |               0 | (null) |    (null) | (null) | (null) |          (null) |

对于调试注释过滤器AND t3.id IS NULL