Supongamos que tiene nodes
tablas como esta:
CREATE TABLE nodes
(
node serial PRIMARY KEY,
parent integer NULL REFERENCES nodes(node),
ts timestamp NOT NULL DEFAULT now()
);
Representa una estructura de árbol similar a un nodo estándar con nodos raíz en la parte superior y varios nodos secundarios que cuelgan de los nodos raíz u otros nodos secundarios.
Insertemos un par de valores de ejemplo:
INSERT INTO nodes (parent)
VALUES (NULL), (NULL), (NULL), (NULL), (1), (1), (1), (1), (6), (1)
, (6), (9), (6), (6), (3), (3), (3), (15);
Ahora quiero recuperar los primeros 10 nodos raíz y todos sus hijos hasta una profundidad de 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;
Esto funciona muy bien y me da el siguiente resultado:
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
Como habrás notado, no hay ORDER BY
cláusula, por lo que el orden no está definido. El orden que ve aquí es de nodos raíz a nodos más profundos.
¿Cómo ordenaría los resultados tal como aparecerían en una vista de árbol expandida, como puede ver en la imagen de ejemplo a continuación?
Básicamente quiero que los nodos secundarios se coloquen justo después de su nodo principal correspondiente. Si dos o más nodos secundarios tienen el mismo nodo primario, quiero que se ordenen por su marca de tiempo. Según el ejemplo anterior, aquí está el orden de salida deseado que estoy tratando de lograr:
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
fuente
depth
dónde viene la columna? No lo veo en la estructura de la tabla inicial.Respuestas:
Una matriz que representa la ruta desde la raíz hasta la hoja debe lograr el orden de clasificación deseado:
Desplace la ruta de uno en uno hacia la raíz y ordene por esa columna adicionalmente:
fuente