Предположим, у вас есть nodes
такие таблицы:
CREATE TABLE nodes
(
node serial PRIMARY KEY,
parent integer NULL REFERENCES nodes(node),
ts timestamp NOT NULL DEFAULT now()
);
Он представляет собой стандартную узловую древовидную структуру с корневыми узлами вверху и несколькими дочерними узлами, свисающими с корневых узлов или других дочерних узлов.
Давайте вставим пару примеров значений:
INSERT INTO nodes (parent)
VALUES (NULL), (NULL), (NULL), (NULL), (1), (1), (1), (1), (6), (1)
, (6), (9), (6), (6), (3), (3), (3), (15);
Теперь я хочу получить первые 10 корневых узлов и всех их дочерних элементов до глубины 4:
WITH RECURSIVE node_rec AS
(
(SELECT 1 AS depth, * FROM nodes WHERE parent IS NULL LIMIT 10)
UNION ALL
SELECT depth + 1, n.*
FROM nodes AS n JOIN node_rec ON (n.parent = node_rec.node)
WHERE depth < 4
)
SELECT * FROM node_rec;
Это прекрасно работает и дает мне следующий результат:
depth | node | parent
-------+------+--------
1 | 1 |
1 | 2 |
1 | 3 |
1 | 4 |
2 | 5 | 1
2 | 6 | 1
2 | 7 | 1
2 | 8 | 1
2 | 10 | 1
2 | 15 | 3
2 | 16 | 3
2 | 17 | 3
3 | 9 | 6
3 | 11 | 6
3 | 13 | 6
3 | 14 | 6
3 | 18 | 15
4 | 12 | 9
Как вы могли заметить, здесь нет ORDER BY
предложения, поэтому порядок не определен. Здесь вы видите порядок от корневых узлов до более глубоких узлов.
Как бы я упорядочил результаты так, как они будут отображаться в расширенном древовидном представлении, как вы можете видеть на следующем рисунке?
Я в основном хочу, чтобы дочерние узлы были размещены сразу после их соответствующего родительского узла. Если два или более дочерних узла имеют один и тот же родительский узел, я хочу, чтобы они сортировались по отметке времени. Основываясь на примере выше, вот желаемый порядок вывода, которого я пытаюсь достичь:
depth | node | parent | ts
-------+------+--------+---------
1 | 1 | | 2014-01-01 00:00:00
2 | 5 | 1 | 2014-01-01 00:10:00
2 | 6 | 1 | 2014-01-01 00:20:00
3 | 9 | 6 | 2014-01-01 00:25:00
4 | 12 | 9 | 2014-01-01 00:27:00
3 | 11 | 6 | 2014-01-01 00:26:00
3 | 13 | 6 | 2014-01-01 00:30:00
3 | 14 | 6 | 2014-01-01 00:36:00
2 | 7 | 1 | 2014-01-01 00:21:00
2 | 8 | 1 | 2014-01-01 00:22:00
2 | 10 | 1 | 2014-01-01 00:23:00
1 | 2 | | 2014-01-01 00:08:00
1 | 3 | | 2014-01-01 00:09:00
2 | 15 | 3 | 2014-01-01 10:00:00
3 | 18 | 15 | 2014-01-01 11:05:00
2 | 16 | 3 | 2014-01-01 11:00:00
2 | 17 | 3 | 2014-01-01 12:00:00
1 | 4 | | 2014-01-01 00:10:00
источник
depth
откуда эта колонка? Я не вижу его в исходной структуре таблицы.Ответы:
Массив, представляющий путь от корня до листа, должен достичь желаемого порядка сортировки:
Сдвиньте путь на один в сторону корня и дополнительно упорядочите по этому столбцу:
источник