SQL Baumstruktur in DB

derocco

Lt. Junior Grade
Registriert
Nov. 2015
Beiträge
349
Ich habe ein Problem it einer DB die ich reverse engineere.

Szenario:

Wir haben eine Baumstruktur in eine DB mit im bsp 2 Tabellen gefüllt.

Ich möchte nun in meinem BSP von der Wurzel alle Kinder bekommen.... (Später dann der weg retour)

Jemand eine Idee wie ich das intelligent schreiben kann?

Code:
----------- TEXT_TABLE ------------
ID  LINK   NAME        TEXT
1   1      Theodor     GROSSVATER
2   2      Martha      MUTTER
3   2      Kurt        VATER
4          Hannes      KIND

----------- LINK_TABLE ------------
ID  LINK   BELONGTO
1   1      Martha      
2   1      Kurt
3   2      Hannes      
4   


Select t.NAME, l.BELONGTO
from TEXT_TABLE t 
JOIN LINK_TABLE l on t.ID = l.id
where t.name = 'Theodor'

Resultat: 

Theodor  Martha
Theodor  Kurt


Select t.NAME, l.BELONGTO, l2.BELONGTO
from TEXT_TABLE t 
JOIN LINK_TABLE l on t.ID = l.id
JOIN TEXT_TABLE t2 on t2.NAME = l.BELONGTO
JOIN LINK_TABLE l2 on t2.ID = l2.id
where t.name = 'Theodor'


Resultat: 

Theodor  Martha  Hannes
Theodor  Kurt    Hannes

Ich hoffe das Bsp mag verdeutlichen was mein Problem ist.

Ich müsste ja weil ich die Baumtiefe nie kenne und die zb auch 50 sein kann zig mal durch TEXT_TABLE tX und LINK_TABLE lX durch joinen was weder performant noch die Lösung sein kann.... :freak: Plus sieht die "Lösung" natürlich nicht aus wie ich mir das wünschen würde.
 
Du solltest viel grundlegender anfangen. Deine Tabellen sind nicht normalisiert. Wo stammen diese her? Wenn von Dir, dann solltest du ganz von vorne anfangen bevor du mit so einem Thema anfängst.
Sprich Datenmodellierung und Normalisierung zuerst verstehen und dann kannst du weiter gehen und Dir SQL anschauen.
 
Das ist mir klar dass die NICHT normalisiert ist.
Ist ja nicht mein Werk, das ganze stammt aus einer software raus im Produktiven betrieb....

Klar ich hätte das auch NIE so gebaut...

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
-> Dreht sich auch um das Thema, scheint ohne die wiederholenden Joins nicht zu gehen...

Irgend jemand noch ein Idee?

Läuft auf DB2 btw.
 
Zuletzt bearbeitet:
Ich weiss nicht genau, ob und wie es in der DB2 funktioniert, aber die Oracle kennt einen Operator, mit der ich das Parent-Element definieren kann. Das Schlüsselwort ist "CONNECT BY". Ich kann mir denken, dass die DB2 hier ebenfalls etwas für anbietet.
 
Ich kann nichts an der Struktur ändern, ich möchte nur eine Analyse darauf machen.

Das Problem ist ich kann nciht mal erkennen in welche Richtung ich mich hangel... Ob ich zur Wurzel gehe oder auf einen Ast raus. :mad:
 
nein nicht möglich.

Das sit auc nur eine Vorarbeit, danacht wenn ich die Record identifiziert habe, dann muss ich da updates fahren...
 
phm666 schrieb:
Ich weiss nicht genau, ob und wie es in der DB2 funktioniert, aber die Oracle kennt einen Operator, mit der ich das Parent-Element definieren kann. Das Schlüsselwort ist "CONNECT BY". Ich kann mir denken, dass die DB2 hier ebenfalls etwas für anbietet.
Es gibt im Standard SQL stattdessen "With", was Oracle mittlerweile auch kennt und soweit ich gelesen habe von DB 2 seit Version 8 beherrscht wird.

Hier ist eine Beispielseite zu "rekursivem" SQL mit DB 2
http://www.mayeruli.de/db2/rekursives-sql.php
 
Die erste Anfrage in Zeile 16 kann nicht das Resultat aus Zeile 21 liefern. Also dass Mutter(Martha) und Vater(Kurt), die Eltern von Hannes, beide Kinder von Großvater(Theo) sind. Problem neben der Inzucht: die Anfrage wird per PK gejoint, Zeile 18, das erzwingt eine 1-zu-1 Beziehung. Resultat der Anfrage sollte sein: Theo ist Vater von Martha, 1-zu-1, Theo kann nur ein Kind haben.

Die 1-zu-1 Beziehung kann nicht richtig sein. Wenn man das Ganze korrigiert und text.link mit link.link verknüpft, kann man die direkten Nachkommen einer Person ermitteln, und die direkten Vorfahren, ... Inzucht bleibt.

(Mit der zweiten Anfrage (Zeile 27) möchte ich mich gar nicht befassen. Da werden Datenfelder gejoint, statt Schlüssel)

Wie dem auch sei. Ich denke nicht, dass man mit diesem Datenmodell die Kindeskinder zu beliebigen Personen finden kann, mit einer Anfrage. Ich kenne nur ein Modell, das so etwas ermöglicht: die sogenannten 'Nested Sets'. Statt Vater-Kind-Beziehungen wird die In-Order-Reihenfolge in den Knoten der Baumstruktur vermerkt als 'links' und 'rechts'. In-Order ist eine Art der Iteration/Sortierung von Baumknoten.

Wen das interessiert sollte nach SQL Nested Sets suchen.
 
fhtagn schrieb:
Die erste Anfrage in Zeile 16 kann nicht das Resultat aus Zeile 21 liefern. Also dass Mutter(Martha) und Vater(Kurt), die Eltern von Hannes, beide Kinder von Großvater(Theo) sind. Problem neben der Inzucht: die Anfrage wird per PK gejoint, Zeile 18, das erzwingt eine 1-zu-1 Beziehung. Resultat der Anfrage sollte sein: Theo ist Vater von Martha, 1-zu-1, Theo kann nur ein Kind haben.

Die 1-zu-1 Beziehung kann nicht richtig sein. Wenn man das Ganze korrigiert und text.link mit link.link verknüpft, kann man die direkten Nachkommen einer Person ermitteln, und die direkten Vorfahren, ... Inzucht bleibt.

(Mit der zweiten Anfrage (Zeile 27) möchte ich mich gar nicht befassen. Da werden Datenfelder gejoint, statt Schlüssel)

Wie dem auch sei. Ich denke nicht, dass man mit diesem Datenmodell die Kindeskinder zu beliebigen Personen finden kann, mit einer Anfrage. Ich kenne nur ein Modell, das so etwas ermöglicht: die sogenannten 'Nested Sets'. Statt Vater-Kind-Beziehungen wird die In-Order-Reihenfolge in den Knoten der Baumstruktur vermerkt als 'links' und 'rechts'. In-Order ist eine Art der Iteration/Sortierung von Baumknoten.

Wen das interessiert sollte nach SQL Nested Sets suchen.


Agree, nested stets habe ich auch gefunden aber das sit nicht das thema, die DB Struktur ist "gottgegeben" und kann nicht verändert werden.
Ich habe keine Ahnung warum die Tabellen so sind. Es gibt noch weitere Konstrukte in dieser DB, die ich null nachvollziehen kann, aber so ist es nun mal.

Interessant ist, dass diese DB so in einem Produkt einer Namhaften Firma porduktiv international verwendet wird. (Namen dar ich keinne nennen)
Ergänzung ()

Andreas_ schrieb:
Es gibt im Standard SQL stattdessen "With", was Oracle mittlerweile auch kennt und soweit ich gelesen habe von DB 2 seit Version 8 beherrscht wird.

Hier ist eine Beispielseite zu "rekursivem" SQL mit DB 2
http://www.mayeruli.de/db2/rekursives-sql.php

With könnte hier der Schlüssel sein. Danke für den Hint
 
Zurück
Oben