Nehmen wir an, Sie haben eine nodes
Tabelle wie diese:
CREATE TABLE nodes
(
node serial PRIMARY KEY,
parent integer NULL REFERENCES nodes(node),
ts timestamp NOT NULL DEFAULT now()
);
Es stellt eine knotenähnliche Standardbaumstruktur mit Wurzelknoten oben und mehreren untergeordneten Knoten dar, die an Wurzelknoten oder anderen untergeordneten Knoten baumeln.
Fügen wir ein paar Beispielwerte ein:
INSERT INTO nodes (parent)
VALUES (NULL), (NULL), (NULL), (NULL), (1), (1), (1), (1), (6), (1)
, (6), (9), (6), (6), (3), (3), (3), (15);
Jetzt möchte ich die ersten 10 Wurzelknoten und alle ihre Kinder bis zu einer Tiefe von 4 abrufen:
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;
Das funktioniert super und gibt mir folgendes Ergebnis:
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
Wie Sie vielleicht bemerkt haben, gibt es keine ORDER BY
Klausel, daher ist die Reihenfolge nicht definiert. Die Reihenfolge, die Sie hier sehen, ist von Wurzelknoten zu tieferen Knoten.
Wie würde ich die Ergebnisse so anordnen, wie sie in einer erweiterten Baumansicht angezeigt würden, wie Sie aus dem folgenden Beispielbild sehen können?
Grundsätzlich möchte ich, dass die untergeordneten Knoten direkt hinter den entsprechenden übergeordneten Knoten platziert werden. Wenn zwei oder mehr untergeordnete Knoten denselben übergeordneten Knoten haben, sollen sie nach ihrem Zeitstempel sortiert werden. Basierend auf dem obigen Beispiel ist hier die gewünschte Ausgabereihenfolge, die ich erreichen möchte:
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
Kolumne kommt? Ich sehe es nicht in der anfänglichen Tabellenstruktur.