ツリー構造が次のようにSQLに実装されているとします。
CREATE TABLE nodes (
id INTEGER PRIMARY KEY,
parent INTEGER -- references nodes(id)
);
この表現でサイクルを作成することはできますが、それを決して起こさせないと仮定しましょう。このテーブルには、ルート(親がnullのレコード)とその子孫のコレクションのみが格納されます。
目標は、テーブル上のノードの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
。
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
。
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データベースで実行できるかどうかを知りたいと思います。