Eri*_*ric 31 sql sqlite hierarchical-data
我有一个简单的sqlite3表,如下所示:
Table: Part
Part SuperPart
wk0Z wk00
wk06 wk02
wk07 wk02
eZ01 eZ00
eZ02 eZ00
eZ03 eZ01
eZ04 eZ01
Run Code Online (Sandbox Code Playgroud)
我需要运行一个递归查询来查找给定SuperPart及其所有子组的所有对.所以我要说我有eZ00.eZ00是eZ01的超级部件,eZ01是eZ03的超级部件.结果必须不仅包括对(eZ00,eZ01)和(eZ01和eZ03),还必须包括对(eZ00,eZ03).
我知道还有其他方法来定义表格,但我在这里别无选择.我知道如果我知道树的深度,我可以使用几个工会,但我不会总是知道我想去的深度.它有助于拥有像WITH RECURSIVE这样的东西,甚至只是WITH(,,)AS x,但对于我搜索过的东西,这在sqlite中是不可能的,对吧?
有没有办法在sqlite3中执行此递归查询?
更新:
当提出这个问题时,SQLite不支持递归查询,但正如@lunicon所述,SQLite现在支持递归CTE,因为3.8.3 sqlite.org/lang_with.html
mu *_*ort 32
如果您有幸使用SQLite 3.8.3或更高版本,那么您可以使用WITH访问递归和非递归CTE :

感谢lunicon让我们了解这个SQLite更新.
在3.8.3之前的版本中,SQLite不支持递归CTE(或者根本不支持CTE),因此SQLite中没有WITH.由于你不知道它有多深,你不能使用标准的JOIN技巧伪造递归CTE.您必须以艰难的方式执行此操作并在客户端代码中实现递归:
根据在带有文档的 sqlite中找到的示例,查询
DROP TABLE IF EXISTS parts;
CREATE TABLE parts (part, superpart);
INSERT INTO parts VALUES("wk0Z", "wk00");
INSERT INTO parts VALUES("wk06", "wk02");
INSERT INTO parts VALUES("wk07", "wk02");
INSERT INTO parts VALUES("eZ01", "eZ00");
INSERT INTO parts VALUES("eZ02", "eZ00");
INSERT INTO parts VALUES("eZ03", "eZ01");
INSERT INTO parts VALUES("eZ04", "eZ01");
WITH RECURSIVE
under_part(parent,part,level) AS (
VALUES('?', 'eZ00', 0)
UNION ALL
SELECT parts.superpart, parts.part, under_part.level+1
FROM parts, under_part
WHERE parts.superpart=under_part.part
)
SELECT SUBSTR('..........',1,level*3) || "(" || parent || ", " || part || ")" FROM under_part
;
Run Code Online (Sandbox Code Playgroud)
会输出
(?, eZ00)
...(eZ00, eZ01)
...(eZ00, eZ02)
......(eZ01, eZ03)
......(eZ01, eZ04)
Run Code Online (Sandbox Code Playgroud)
正如“应该是”预期的那样
递归表的初始记录可以替换为
VALUES ((SELECT superpart FROM parts WHERE part='eZ00'), 'eZ00', 0)
Run Code Online (Sandbox Code Playgroud)
为了获得初始超部分的父级,尽管在这种情况下根本没有父级。
在此SQLite版本3.8.3中,2014-02-03增加了对CTE的支持.这是文档WITH子句 示例:
WITH RECURSIVE
cnt(x) AS (
SELECT 1
UNION ALL
SELECT x+1 FROM cnt
LIMIT 1000000
)
SELECT x FROM cnt;
Run Code Online (Sandbox Code Playgroud)
这是我能想到的最基本的查询,它生成一个系列,我们从 1,2 开始并不断加 1 直到达到 20。没有多大用处,但稍微玩一下这将有助于您构建更复杂的递归查询
最基本的系列
WITH b(x,y) AS
(
SELECT 1,2
UNION ALL
SELECT x+ 1, y + 1
FROM b
WHERE x < 20
) SELECT * FROM b;
Run Code Online (Sandbox Code Playgroud)
印刷
1|2
2|3
3|4
4|5
5|6
6|7
7|8
8|9
9|10
10|11
11|12
12|13
13|14
14|15
15|16
16|17
17|18
18|19
19|20
20|21
Run Code Online (Sandbox Code Playgroud)
这是另一个生成斐波那契数的简单示例,我们从 a = 0, b = 1 开始,然后转到 a = b, b = a + b 就像您在任何编程语言中所做的一样
斐波那契数列
WITH b(x,y) AS
(
SELECT 0,1
UNION ALL
SELECT y, x + y
FROM b
WHERE x < 10000
) select * FROM b;
Run Code Online (Sandbox Code Playgroud)
印刷
0|1
1|1
1|2
2|3
3|5
5|8
8|13
13|21
21|34
34|55
55|89
89|144
144|233
233|377
377|610
610|987
987|1597
1597|2584
2584|4181
4181|6765
6765|10946
10946|17711
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26677 次 |
| 最近记录: |