Предположим, что древовидная структура реализована в SQL следующим образом:
CREATE TABLE nodes (
id INTEGER PRIMARY KEY,
parent INTEGER -- references nodes(id)
);
Хотя в этом представлении могут быть созданы циклы, давайте предположим, что мы никогда этого не допустим. В таблице будет храниться только коллекция корней (записей, где parent равен нулю) и их потомков.
Цель состоит в том, чтобы, учитывая идентификатор узла в таблице, найти все узлы, которые являются его потомками.
A является потомком B , если родительский номер A равен B или A ' s родитель является потомком 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.