[SQL (Firebird)] Rekursion und Baumstruktur

OnkelHomie

Grünschnabel
Hallo zusammen,

ich stehe gerade vor einem, für mich recht kniffligen, SQL Problem. Ich muss dazu sagen das ich bisher kaum was mit (Firebird)SQL gemacht habe und dort auch erst recht nichts mit Rekursionen, also bitte bei Anfängerfehlern nachsichtig sein ;)

Vielleicht kann mir ja jemand helfen.

Ausgangssituation:
2 Tabellen (T1, T2) sollen einen Baum ergeben dessen Struktur beispielsweise wie folgt aussieht:

Code:
Element aus T1
|
| - Element 1 aus T2
|   |
|   |- Element  1.1 aus T2
|   |
|   |- Element  1.2 aus T2
|      |
|      |-Element 1.2.1 aus T2
|
| - Element 2 aus T2
...

Wichtig hierbei ist, dass ein Element aus T1 niemals das Child eines Elements aus T2 seien kann und es auch immer nur ein Element aus T1 im Baum als Root gibt.

Der problematische Teil stellt nun also die Anordnung der Elemente aus T2 dar.

Ich suche jetzt nach Möglichkeit eine rekursive SQL Anweisung um die korrekte Baumstruktur zu bekommen.

Einzelne Elemente sehen dabei wie folgt aus (E1 = Element aus T1, E2 = Element aus T2):

E1.ID
E2.ID, E2.RefUebergeordneteID (kann sowohl eine E1.ID als auch eine E2.ID sein), E2.PositionNummer

Die anderen Attribute sind hier unwichtig, es geht nur um die Zuordnung der IDs bzw. eben der referenzierten IDs.

Die PositionNummer wird auf den einzelnen Ebene als Beispiel wie folgt vergeben:

Code:
Element 1 = Position 1
|
| - Element 1.1 = Position 1
|  |
| - Element 1.2 = Position 2
|
|
Element 2 = Position 2

Das Problem ist, dass die IDs jeweils GUI-IDs sind und keine aufeinander folgenden Indizes und die Positions Nummern halt für einzelne Abschnitte vergeben sind und nicht einfach fortlaufend. Diese Struktur kann ich auch nicht groß umstellen. Insgesamt habe ich leider wenig Möglichkeiten die bereits vorhandene Struktur zu erweitern, ließe sich aber ggf. drüber diskutieren.

Mein Ansatz sieht nun bisher wie folgt aus:

Code:
WITH  RECURSIVE rek (ID, RefUebergeordneteID, PosNummer, stufe)
AS (
    SELECT ID, RefUebergeordneteID, 1 as stufe
    FROM T2
    Where RefUebergeordneteID =  ' <eine bestimmte GUI-ID>'
    UNION ALL
    SELECT child.ID, child.RefUebergeordneteID, child.PosNummer, parent.stufe+1
    FROM rek parent,
        T2 child
     INNER JOIN rek parent
    ON child.RefUebergeordneteID= parent.ID
)
SELECT DISTINCT ID, RefUebergeordneteID, PosNummer, stufe
FROM rek
Order by stufe

Leider ist die Sortierung dann noch nicht ganz korrekt. Aber ich schaffe es nicht da noch einen weietren passenden "Counter" oder ein Order/Group by an einer passenden Stelle reinzusetzen.

Wichtig ist auch noch das eine nested Struktur nicht in Frage kommt, da ständig Daten in die Tabelle 2 der Datenbank an beliebigen Stellen geschrieben, kopiert oder verschoben werden können und dann irgendwann der Aufwand zu groß wird die ganze Struktur immer neu durchzurechnen.

Wäre klasse wenn jemand vielleicht einen Denkanstoß bzw. einen Lösungsansatz hätte :)
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück