【发布时间】:2016-12-13 13:03:20
【问题描述】:
https://www.sqlite.org/lang_with.html#withorderby 展示了递归级别的排序如何将树的深度优先顺序更改为广度优先顺序的示例。理查德·希普 http://sqlite.1065341.n5.nabble.com/why-does-the-recursive-example-sort-alphabetically-td80404.html 说递归部分的order-by有一个特殊的含义:决定递归的顺序。
我已经在递归级别以外的字段上使用 order-by 并且......我无法预测结果。 :( 有人可以解释一下它是如何工作的吗?
基本上,让我们看一个类似于 sqlite 文档(上面的第一个链接)中的 Alice/Bob/Cindy 的示例,但名称有点混淆(在树中不是按字母顺序排列,而是以随机顺序插入)然后在递归部分使用“按名称排序”(而不是递归级别)。
CREATE TABLE child_parent(
name TEXT PRIMARY KEY,
parent TEXT
);
INSERT INTO child_parent VALUES('KKK','HHH');
INSERT INTO child_parent VALUES('HHH','LLL');
INSERT INTO child_parent VALUES('MMM','CCC');
INSERT INTO child_parent VALUES('CCC','QQQ');
INSERT INTO child_parent VALUES('QQQ','LLL');
INSERT INTO child_parent VALUES('TTT','QQQ');
INSERT INTO child_parent VALUES('AAA','HHH');
INSERT INTO child_parent VALUES('EEE','TTT');
INSERT INTO child_parent VALUES('UUU','CCC');
INSERT INTO child_parent VALUES('FFF','MMM');
INSERT INTO child_parent VALUES('LLL',NULL);
child_parent 结构是:
-- LLL -> QQQ
-- -> TTT
-- -> EEE
-- -> CCC
-- -> UUU
-- -> MMM
-- -> FFF
-- -> HHH
-- -> AAA
-- -> KKK
首先选择 - 使用“ORDER BY new_name asc”
WITH RECURSIVE
tree(name,level) AS (
SELECT cp.name, 0
FROM child_parent cp
WHERE cp.parent IS NULL
UNION ALL
SELECT ch.name AS new_name, tree.level+1 AS new_lvl
FROM child_parent ch
INNER JOIN tree ON ch.parent=tree.name
ORDER BY new_name ASC
)
SELECT *, substr('...................',1,level*3) || name FROM tree;
-- name level substr('...................',1,level*3) || name
-- ---------- ---------- -----------------------------------------------
-- LLL 0 LLL
-- HHH 1 ...HHH
-- AAA 2 ......AAA
-- KKK 2 ......KKK
-- QQQ 1 ...QQQ
-- CCC 2 ......CCC
-- MMM 3 .........MMM
-- FFF 4 ............FFF
-- TTT 2 ......TTT
-- EEE 3 .........EEE
-- UUU 3 .........UUU
首先选择 - 使用“ORDER BY new_name desc”
WITH RECURSIVE
tree(name,level) AS (
SELECT cp.name, 0
FROM child_parent cp
WHERE cp.parent IS NULL
UNION ALL
SELECT ch.name AS new_name, tree.level+1 AS new_lvl
FROM child_parent ch
INNER JOIN tree ON ch.parent=tree.name
ORDER BY new_name DESC
)
SELECT *, substr('...................',1,level*3) || name FROM tree;
-- name level substr('...................',1,level*3) || name
-- ---------- ---------- -----------------------------------------------
-- LLL 0 LLL
-- QQQ 1 ...QQQ
-- TTT 2 ......TTT
-- HHH 1 ...HHH
-- KKK 2 ......KKK
-- EEE 3 .........EEE
-- CCC 2 ......CCC
-- UUU 3 .........UUU
-- MMM 3 .........MMM
-- FFF 4 ............FFF
-- AAA 2 ......AAA
基本上问题是:如何考虑数据库行为来预测最后两个查询的结果将如上所示。您能否描述一步一步发生的事情,例如在每个递归级别?
SQLite 3.15.2.0.37
【问题讨论】:
标签: recursion sqlite recursive-query