如何逆转SQLite CTE的顺序

时间:2014-06-17 05:40:46

标签: sqlite reverse common-table-expression

如果我做一个简单的选择,我可以使用ORDER BY订购结果。但我不能用WITH RECURSIVE CTE来做这件事,因为我用它来查找从树中的叶子到根的路径,并且CTE创建结果的顺序不是可以的顺序通过排序获得,因此没有ORDER BY我可以反转以获得相反的顺序。

我遇到的问题是,这构造了从leaf到root的结果,但是对于查询的后续部分,我需要它以相反的顺序,从根到叶。但是我无法以这种方式构造查询,因为它会关闭树中的所有分支而不是我需要的单个路径。因此,我需要以某种方式扭转所得CTE的顺序。我怎样才能做到这一点?

我已经做了一些寻找,并且对于其他(非SQLite)数据库存在一些类似的问题,这似乎表明CTE表的结果实际上没有任何已定义的顺序。我不确定SQLite是否也是如此 - 我总是看到它将同一个子表中的表输出到父顺序,实际上还有其他情况(例如创建临时表as in a previous question I asked),如果表格不能保证具有此属性,它会破坏唯一可能的解决方案,使其成为一个不可能解决的问题。

2 个答案:

答案 0 :(得分:1)

documentation说:

  

recursive-select的ORDER BY子句可用于控制树的搜索是深度优先还是广度优先。

但是,您想要对CTE的最终输出进行排序。 这可以很容易地完成,因为您使用普通的SELECT来访问CTE:

WITH RECURSIVE test1(id, parent) AS (
    VALUES(3, 2)
    UNION ALL
    SELECT test.id, test.parent
    FROM test JOIN test1 ON test1.parent = test.id)
SELECT *
FROM test1
ORDER BY id     -- this sorts normally

答案 1 :(得分:0)

您可以在订单中使用多个元素。例如,以下将在执行深度优先搜索后按名称对树进行排序。在这里,我首先按LEVEL降序排序然后NAME升序。输出将是一个排序树,其子项位于相应父级之下。

WITH RECURSIVE TEMPTREE (
        id,
        name,
        level
    )
    AS (
        SELECT flow_id,
               name,
               0
          FROM DATATABLE
         WHERE parent_id IS NULL
        UNION ALL
        SELECT DATATABLE.id,
               DATATABLE.name,
               TEMPTREE.level + 1
          FROM DATATABLE
               JOIN
               TEMPTREE ON DATATABLE.parent_id = TEMPTREE .id 
         ORDER BY 3 DESC, 2 ASC
    )
    SELECT substr('..........', 1, level * 3) || name AS Name,
           id
      FROM TEMPTREE;