如果我做一个简单的选择,我可以使用ORDER BY
订购结果。但我不能用WITH RECURSIVE
CTE来做这件事,因为我用它来查找从树中的叶子到根的路径,并且CTE创建结果的顺序不是可以的顺序通过排序获得,因此没有ORDER BY
我可以反转以获得相反的顺序。
我遇到的问题是,这构造了从leaf到root的结果,但是对于查询的后续部分,我需要它以相反的顺序,从根到叶。但是我无法以这种方式构造查询,因为它会关闭树中的所有分支而不是我需要的单个路径。因此,我需要以某种方式扭转所得CTE的顺序。我怎样才能做到这一点?
我已经做了一些寻找,并且对于其他(非SQLite)数据库存在一些类似的问题,这似乎表明CTE表的结果实际上没有任何已定义的顺序。我不确定SQLite是否也是如此 - 我总是看到它将同一个子表中的表输出到父顺序,实际上还有其他情况(例如创建临时表as in a previous question I asked),如果表格不能保证具有此属性,它会破坏唯一可能的解决方案,使其成为一个不可能解决的问题。
答案 0 :(得分:1)
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;