mySql alle untergeordnete ids finden

Hallo zusammen, ich habe eine SQl-Tabelle mit Ids, parent-ids und der Info, auf welcher Ebene sich eine id befindet.

ID I Parent_id I Level

1 I 0 I 1

2 I 1 I 2

3 I 1 I 2

4 I 2 I 3

5 I 2 I 3

Jetzt möchte ich gerne ALLE untegeordneten Ids zu einer Gegebenen finden.

Also, wenn die Id 1 ist, sollen die Ids 2, 3, 4, 5 ausgegeben werden, da diese der Id 1 untergeordnet sind.

gibt es dafür eine MySql Abfrage?
Ich würde es nur über eine Schleife mit php hinkriegen, was dann aber in mehreren Abfragen resultieren würde und diesen erhöhten Traffic möchte ich mir gerne ersparen.

Mfg,
David

Das geht mit SQL nicht, da man theoretisch unendlich tief JOINen müsste. Du musst also mit Logik in deinem Skript leben.

Gruß,

Michael

Hallo David,

ich verstehe Deine Frage bzw. Dein Beispiel nicht. Was verstehst Du unter „untergeordnete IDs“?

Nach meinem Verständnis wären in Deinem Beispiel die Sätze mit den IDs 2 und 3 Untergeordnete von 1, da sie 1 als ParentID haben.

Wieso sind 4 und 5 auch untergeordnet?


Bfn
Michael

Hallo David,

Erstmal kannst Du Dir das Level sparen. Das lässt sich berechnen. Zweitens kannst Du da zwei Ansätze wählen:
Adjacency List Model oder Nested Set Model.

Das erste geht in die Richtung die du angefangen hast. Vorteil: Leicht zu schreiben und zu updaten
Nachteil: schwer zu lesen

Nested Set Model hat genau die verkehrten Eingenschaften: Leicht zu lesen, schwer zu updaten.

Hier ein Beispiel das ziemlich genau zu Deinem Problem passt (aus dem Stackoverflow Artikel) und den Unterschied zwischen dem Adjacency List Model und dem Nested Set Model aufzeigt:

http://mikehillyer.com/articles/managing-hierarchica…

Da Nested Set Model ziemlich komisch ist hier noch ein guter Artikel dazu:
http://www.evanpetersen.com/item/nested-sets.html

Zu diesem Thema gibt es einen Haufen Erklärungen, hier nur mal als Referenz erwähnt:

http://falsinsoft.blogspot.nl/2013/01/tree-in-sql-da…

http://www.codeproject.com/Articles/4155/Improve-hie…

Zur Vollständigkeit gibt es noch Recursive SQL Abfragen und das Materialized Path Model. Allerdings ist Recursive SQL nur bei bestimmten Datenbanken verwendbar.

Auf Materialized Paths wird hier nochmal vergleichend eingegangen:
http://www.rampant-books.com/art_vadim_nested_sets_s…

letztendlich wäre das bei dir die Speicherung des ganzen Pfads als für ID 4 würde als ParentId (oder dann besser „Path“) stehen „0.2.4“. Damit wäre der ganze Pfad abgebildet und deine SQL Abfragen sind wesentlich einfacher.

Schreib gerne nochmal, wenn Du weiß welche Algorithmus du verwenden möchtest falls Du hilfe brauchst.

Grüße
CCarpo

Hallo,

bitte was? Das Beispiel erschließt sich mir nicht so ganz auf den ersten Blick.

Bezieht sich „Parent_id“ auf „ID“, d.h. Zeile 5 (ID=5) ist (wegen Parent_id=2) der Zeile 2 untergeordnet? Und Zeile 2 dann entsprechend Zeile 1, usw.?

Wenn das so zu verstehen ist, dann lautet meine Antwort wie folgt:
Eine generische Abfrage dazu gibt es nicht. UNION, INTERSECT oder auch JOIN entfallen, da alles in einer Tabelle steht. Unterabfragen würden nur die nächste Ebene, nicht aber alle möglichen und noch eventuell darauf folgende Unterebenen auflisten.

Die gewählte Datenhaltung bzw. -struktur entspricht einem Baum mit mehreren Ebenen. Die angebrachteste Lösung für mich wäre hier eine „Stored Procedure“ zu verwenden.

Falls hier Links erlaubt sind, siehe:
http://www.delphipraxis.net/155671-%5Bsql%5D-kaskadi…

und darin erwähnt:

http://www.delphipraxis.net/108799-baumzusammenstell…

Das sollte helfen.

So long.

Hallo David,

was Du benötigst ist der Suchbegriff „nested set“.

http://www.klempert.de/nested_sets/
http://www.php-resource.de/tutorials/tutorial,21,Das…

MfG Georg V.

Hallo David,

auswendig kann ich Dir da leider nicht helfen und ich habe die nächsten zwei Wochen keinen PC zur Hand, um es mal auszuprobieren - Urlaub :smile:

Solltest Du bis dahin noch keine Lösung haben, darfst Du Dich dann gerne nochmal bei mir melden.

Gruß,
Michael

Hallo David,

…Die gibt, die gibt es, aber nicht von mir.
Habe einige Versuche mit einer einfachen DB gemacht (MS Access ist für Prozeduren ungeeignet), um mir meine momentane MySQL Umgebung nicht zu verändern. Dabei werden alle Sub-Daten aller Daten ausgegeben, jedoch ohne die Festlegung des Startpunkts (ID=1):
SELECT I.ID, I.Parent_id
FROM Tabelle1 AS I INNER JOIN Tabelle1 AS S1 ON I.Parent_id = S1.ID
WHERE S1.ID=1;

Um das Ganze variabel zu gestalten, wirst Du um eine Prozedur nicht herum kommen. Schau mal hier:
http://www.dbforums.com/microsoft-sql-server/1682235…

Evtl. hat ein Mitbestreiter eine direkte Lösung parat.

Hallo David,

wenn ich deine Frage richtig verstanden hab, müsste das sowas sein:

SELECT * WHERE Parent_id = 1

Beste Grüße und viel Erfolg

Guten Tag,
mit einer einfachen MySQL-Abfrage wird dies etwas schwierig. Am besten wird dies wohl mit einer Stored Procedure gehen, da hier Berechnungslogik in der Datenbank ausgelagert werden kann.
Informationen finden Sie unter:
http://dev.mysql.com/doc/refman/5.1/de/create-proced…
http://www.mysqltutorial.org/mysql-stored-procedure-…

Bitte beachten Sie, dass nicht alle Datenbanktypen stored-procedures unterstützen.

Ich hoffe ich konnte damit etwas weiter helfen.