假设一个树结构在 SQL 中是这样实现的:
CREATE TABLE nodes (
id INTEGER PRIMARY KEY,
parent INTEGER -- references nodes(id)
);
尽管可以在此表示中创建循环,但我们假设我们永远不会让这种情况发生。该表将仅存储根(父为空的记录)及其后代的集合。
目标是,给定表中一个节点的 id,找到它的所有后代节点。
A 是 B 的后代,如果 A 的父代是 B 或 A 的父级是 B 的后代。注意递归定义。
这是一些示例数据:
INSERT INTO nodes VALUES (1, NULL);
INSERT INTO nodes VALUES (2, 1);
INSERT INTO nodes VALUES (3, 2);
INSERT INTO nodes VALUES (4, 3);
INSERT INTO nodes VALUES (5, 3);
INSERT INTO nodes VALUES (6, 2);
代表:
1
`-- 2
|-- 3
| |-- 4
| `-- 5
|
`-- 6
我们可以通过这样做来选择 1
的(直接) child :
SELECT a.* FROM nodes AS a WHERE parent=1;
我们可以通过这样做来选择 1
的子孙:
SELECT a.* FROM nodes AS a WHERE parent=1
UNION ALL
SELECT b.* FROM nodes AS a, nodes AS b WHERE a.parent=1 AND b.parent=a.id;
我们可以通过这样做来选择 1
的 child 、孙子和曾孙:
SELECT a.* FROM nodes AS a WHERE parent=1
UNION ALL
SELECT b.* FROM nodes AS a, nodes AS b WHERE a.parent=1 AND b.parent=a.id
UNION ALL
SELECT c.* FROM nodes AS a, nodes AS b, nodes AS c WHERE a.parent=1 AND b.parent=a.id AND c.parent=b.id;
如何构建查询以获取节点 1
的所有后代而不是固定深度的查询?看来我需要创建一个递归查询或其他东西。
我想知道使用 SQLite 是否可以进行这样的查询。但是,如果这种类型的查询需要 SQLite 中不可用的功能,我很想知道它是否可以在其他 SQL 数据库中完成。
最佳答案
一些数据库允许使用递归公用表表达式,但 SQLite 不允许。
您可以考虑更改表定义。使用这样的表,很容易查询 1 的所有后代:
id (varchar)
--------------
001
001002
001002003
001002003004
001002003005
001002006
这允许您查询 1 的所有后代,例如:
SELECT * FROM YourTable WHERE id LIKE '001%'
这听起来有点古怪,但在实践中效果很好。
关于SQL选择一行的后代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2742242/