Wenn dein
DBMS rekursive
SQL-Befehle kennt, dann kannst du für jeden Knoten zählen wie viele Eltern der hat und schon weißt du die Tiefe.
Außerdem fragst du das selber schon rekursiv ab, also mußt du dir nur merken in welcher Ebene du gerade bist und der aktuelle Knoten ist dann Eines tiefer.
Im Grunde kann man auch gleich
DB-seitig die Ebene ermitteln und zusammen mit den Eltern alle Datensätze fertig sortiert ausgeben und muß dann nur noch in Ruhe zeichnen, ohne das über mehrere SELECTS abzufragen.
Ich hatte soeinen Code auch schonmal gesehn, wo man das
Query auf CachedUpdate aktiviert hatte.
Dann nahm man sich einen Datensatz, ging per Locate so lange hoch, bis man keinen Elternknoten fand.
Danach dann rekursiv im selben
Query per Locate die Kinder suchen und sie löschte, wenn eingefügt. (man könnte sich auch in einer Liste speichern, was schon verarbeitet wurde)
Und danach das wiederholen, bis es keine Datensätze mehr gibt. (das Letzte war, falls es Probleme in der Stuktur/Daten gibt, damit dann dennoch alles ausgegeben wird)
Ich hatte mir da auch or Kuzrem ein böses SELECT in Postgres geschrieben, um in einem DBGrid die selbe Reihenfolge zu haben, wie im TreeView.
SQL-Code:
SELECT
sd_id, sd_name,
sd_parentid,
...
(SELECT array_to_string(array_agg(to_char(x_id, 'FM00009')), '-')::VARCHAR(250) FROM (
WITH RECURSIVE temp (x_depth, x_id, x_parentid) AS (
(SELECT 0, x.sd_id, x.sd_parentid
FROM SettingsDyn AS x
WHERE x.sd_id = SettingsDyn.sd_id
UNION
SELECT 666, 0, NULL) -- virtueller Wurzel-Knoten
UNION ALL
(SELECT x_depth+1, x.sd_id, x.sd_parentid
FROM SettingsDyn AS x
JOIN temp ON x_parentid = x.sd_id
WHERE x_depth < 32)
) SELECT * FROM temp ORDER BY x_depth DESC
) AS temp) AS sd_order
FROM SettingsDyn
ORDER BY sd_order
[*] max(x_depth) ergäbe die Tiefe
SQL-Code:
(WITH RECURSIVE temp (x_depth, x_id, x_parentid) AS (
(SELECT 0, x.sd_id, x.sd_parentid
FROM SettingsDyn AS x
WHERE x.sd_id = SettingsDyn.sd_id)
UNION ALL
(SELECT x_depth+1, x.sd_id, x.sd_parentid
FROM SettingsDyn AS x
JOIN temp ON x_parentid = x.sd_id
WHERE x_depth < 32)
) SELECT max(x_depth) FROM temp) AS DieTiefe
[*] oder x_id gibt einfach ALLE Eltern zurück (hier inkl. sich selber), was man dann sonstwie kombinieren kann,
hier z.B. als ein String, der für die Sortierung nutzbar ist. (der Tree ist über die IDs sortiert, also stehen hier die IDs der Prarents in der richtigen Reihenfolge im String)
Code:
00000
00001
00001_00002
00001_00002_00003
00001_00004
00002
....
Hier könnte man auch auf x_depth verzichtgen und über Length(sd_order)/6 die Tiefe holen, falls/da man nur eine Spalte zurückgeben kann.
Sonst müsste man das besser in eine Funktion auslagern oder es als LATERAL JOIN anhängen.