SQL:按树排序但跳过关闭的子树

时间:2017-02-20 13:28:53

标签: sql sqlite

我有下表。这是一个树结构,其中path列显示从树的根到特定节点的完整路径:

Path    | ParentName | ChildName | includeSubTree
1       | Null       | Root      | true
1.1     | Root       | RC1       | true 
1.1.1   | RC1        | RC11      | true
1.2     | Root       | RC2       | false
1.2.1   | RC2        | RC21      | true
1.2.1.1 | RC21       | RC211     | true

我的目标是选择一个声明:

  1. 返回所有行
  2. 按路径排序
  3. 忽略具有includeSubTree设置为false的父级的所有行
  4. 采用上面的例子,Path 1.2将includeSubtree设置为false因此我想忽略它的所有子节点,无论它们是否将includeSubtree设置为true或false。

    因此,我的查询只返回以下路径:

    1
    1.1
    1.1.1
    

    基本上我要做的是暂时删除整个子树。

    我已经坚持了很长一段时间了,想知道是否有人可以给我一些指示?

    我目前正在使用SQLite,但很高兴能够使用其他SQL系统的答案。到目前为止,我已达到:

    SELECT * 
    FROM TreeStructure 
    WHERE includeSubTree = true 
    ORDER BY Path;
    

    这里显而易见的问题是,这将包括1.2.1,即使1.2将includeSubTree设置为false。

    我正处于这个项目的开始阶段,很高兴在必要时更改架构。

1 个答案:

答案 0 :(得分:0)

嗯,嗯。 。 。您可以将相关子查询与exists一起使用,以查看是否应排除某些内容。

select t.*
from tree t
where not exists (select 1
                  from tree t2
                  where t2.includeSubTree = false and
                        t.path like concat(t2.path, '.%')
                 ) and
      t.includeSubTree = true;

注意:虽然concat()是ANSI标准,但有些数据库将其拼写为+||,甚至是&