Supponiamo che tu abbia una nodes
tabella come questa:
CREATE TABLE nodes
(
node serial PRIMARY KEY,
parent integer NULL REFERENCES nodes(node),
ts timestamp NOT NULL DEFAULT now()
);
Rappresenta una struttura ad albero standard simile a un nodo con nodi radice nella parte superiore e diversi nodi figlio che pendono da nodi radice o altri nodi figlio.
Inseriamo un paio di valori di esempio:
INSERT INTO nodes (parent)
VALUES (NULL), (NULL), (NULL), (NULL), (1), (1), (1), (1), (6), (1)
, (6), (9), (6), (6), (3), (3), (3), (15);
Ora voglio recuperare i primi 10 nodi root e tutti i loro figli fino a una profondità di 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;
Funziona benissimo e mi dà il seguente risultato:
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
Come avrai notato, non esiste una ORDER BY
clausola, quindi l'ordine non è definito. L'ordine che vedi qui va dai nodi radice a nodi più profondi.
Come posso ordinare i risultati come apparirebbero in una vista ad albero espanso, come puoi vedere dall'immagine di esempio qui sotto?
In pratica, desidero che i nodi figlio vengano posizionati subito dopo il nodo genitore corrispondente. Se due o più nodi figlio hanno lo stesso nodo genitore, voglio che vengano ordinati in base al loro timestamp. Sulla base dell'esempio sopra, ecco l'ordine di output desiderato che sto cercando di ottenere:
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
colonna? Non lo vedo nella struttura iniziale della tabella.