Entwickler-Ecke
Datenbanken - zwei JOINs auf die gleiche Referenz-Tabelle ausführen
Narses - Mo 22.06.09 14:17
Titel: zwei JOINs auf die gleiche Referenz-Tabelle ausführen
Moin!
Ich hab mal wieder ein (MySQL-)Problem und steh auf´m Schlauch... :roll:
Hier das abstrakte Problem: Ich habe zwei Tabellen, t1 (id,a,b,c) und t2 (id,name), wobei t1.a auf t2.id verweist, allerdings t1.b zeigt auch auf t2.id. Zum besseren Verständnis: t1 enthält einen Vorgang, der von zwei Leuten bearbeitet wird (a,b), deren Details in t2 vorgehalten werden.
Wie formuliere ich nun ein SELECT, dass mir die Datensätze aus t1 mit den Namen aus t2 ergänzt abliefert?! :gruebel:
cu
Narses
BenBE - Mo 22.06.09 14:24
SQL-Anweisung
1:
| SELECT t.*, pa.*, pb.* FROM t1 AS t INNER JOIN t2 AS pa ON t1.a = pa.id INNER JOIN t2 AS pb ON t1.b = pb.id WHERE 42 |
Alternativ auch möglich:
SQL-Anweisung
1:
| SELECT t.*, pa.*, pb.* FROM t1 AS t, t2 AS pa, t2 AS pb WHERE t1.a = pa.id AND t1.b = pb.id AND 42 |
Rest sollte logisch folgen ...
Narses - Mo 22.06.09 14:27
Moin!
BenBE hat folgendes geschrieben : |
SQL-Anweisung 1:
| SELECT t.*, pa.*, pb.* FROM t1 AS t INNER JOIN t2 AS pa ON t1.a = pa.id INNER JOIN t2 AS pb ON t1.b = pb.id WHERE 42 | |
Ich hab aber nur eine Personen-Tabelle, das ist ja mein Problem... :?
cu
Narses
BenBE - Mo 22.06.09 14:34
Siehe hinten im JOIN die beiden AS-Klauseln ... Damit wird die Nachschlagetabelle t2 zweimal eingebunden; kann also bei großen Datenmengen zu recht großen Kreuzprodukten führen. Hier bedarf es einem recht aktuellen MySQL, damit das sauber optimiert wird.
Alternativ kann man das aber auch in 2 Abfragen lösen, muss dann aber das Lookup selber regeln:
SQL-Anweisung
1:
| SELECT t2.* FROM t2 WHERE t2.id IN (SELECT t1.a FROM t1 WHERE 42 UNION SELECT t1.b FROM t1 WHERE 42) |
Ist zwar nicht ideal, spart dafür aber grad bei großen Tabellen sehr viel Speicher. In der Regel dürfte aber obige Variante mit dem Cross Join wesentlich performanter laufen, da im Gegensatz zur UNION SELECT-Variante durch einen guten Optimierer nur einmal auf t2 SELECTED werden muss.
Narses - Mo 22.06.09 14:40
Moin!
Ah, OK. :idea: Ich probier das mal aus, danke erstmal. ;)
cu
Narses
Delete - Mo 22.06.09 14:57
Sind die Felder a, b und c für die Personen-IDs gedacht? Dann stimmt Deine Normalisierung nicht.
BenBE - Mo 22.06.09 15:09
DeddyH hat folgendes geschrieben : |
Sind die Felder a, b und c für die Personen-IDs gedacht? Dann stimmt Deine Normalisierung nicht. |
Solange überhaupt normalisiert ist, passt's doch :P Außerdem ist das Beispiel rein fiktiv - Ähnlichkeiten zu real existierenden Datenbanken sind sicherlich
REIN ZUFÄLLIG! :mrgreen:
Delete - Mo 22.06.09 15:11
Wer's glaubt, wird selig ;)
Narses - Mo 22.06.09 16:21
Moin!
DeddyH hat folgendes geschrieben : |
Sind die Felder a, b und c für die Personen-IDs gedacht? Dann stimmt Deine Normalisierung nicht. |
Zumindest c ist keine Personen-ID, sondern einfach eine zusätzliche Info des Vorgangs. Kannst du das mal etwas erläutern? :?
cu
Narses
Delete - Mo 22.06.09 16:50
Wenn ich das richtig verstanden habe, können einem Vorgang bis zu 2 Personen zugeordnet sein, wohingegen vermutlich jede Person mehreren Vorgängen zugeordnet sein kann, ist das so richtig? Das wäre ja dann die klassische m:n-Beziehung, die man über eine Zwischentabelle auflöst. Wenn es später mal mehr mögliche Personen je Vorgang werden sollten, musst Du bei Deiner bisherigen Variante die Tabellenstruktur ändern, was bei meiner nicht nötig ist.
Narses - Mo 22.06.09 17:40
Moin!
DeddyH hat folgendes geschrieben : |
Wenn ich das richtig verstanden habe, können einem Vorgang bis zu 2 Personen zugeordnet sein, wohingegen vermutlich jede Person mehreren Vorgängen zugeordnet sein kann, ist das so richtig? |
Im Prinzip ja, es sind allerdings immer genau 2 Personen einem Vorgang zugeordnet (kann sich auch nicht ändern), also 2:n. :nixweiss:
DeddyH hat folgendes geschrieben : |
Das wäre ja dann die klassische m:n-Beziehung, die man über eine Zwischentabelle auflöst. |
Wenn es n:m wäre, hätte ich eine weitere Tabelle, ja. ;)
DeddyH hat folgendes geschrieben : |
Wenn es später mal mehr mögliche Personen je Vorgang werden sollten, musst Du bei Deiner bisherigen Variante die Tabellenstruktur ändern, was bei meiner nicht nötig ist. |
Welche Version meinst du? Habe in deinen Beiträgen keinen Vorschlag gesehen? :lupe:
Und kannst du nochmal erläutern, was du mit "Normalisierung" bezogen auf den Beitrag oben meinst? :gruebel:
cu
Narses
Delete - Mo 22.06.09 17:46
Gut, wenn es immer genau 2 Personen sind, ist das kein Problem. Ich hatte hingegen angenommen, dass es bis zu 2 Personen sein könnten, da wäre die Variante mit Zwischentabelle (die ich mit "meiner" meinte) die bessere Lösung gewesen, da man sonst mit INNER JOINs kein Ergebnis bekommt, wenn auch nur eins der beiden Felder NULL ist.
Narses - Mo 22.06.09 18:51
Moin!
Alles klar, funktioniert. ;) Vielen Dank an alle "Mitarbeiter". :zustimm:
cu :wave:
Narses
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!