Kann ein JOIN mehrere Tabellen umfassen?
Gast
- datenbank
Hallo,
per join möchte ich einen Personensatz hinzufügen. In dem Satz ist eine ort_id und den zugehörigen Ortssatz brauche ich auch:
LEFT JOIN "personen" per3
,"orte" ort3
ON per3.id = xxx.person_id
AND ort3.id = per3.ort_id
Nun wird mir für diese Zeilen "1064: You have an error ..." angezeigt. Habe versucht, den Fehler durch Klammer setzen zu beheben, Fehler bleibt.
Ich habe erstmalig probiert, mit dem join zwei Tabellen ansprechen. Geht das?
Gruß, Gast
Hallo,
LEFT JOIN "personen" per3
,"orte" ort3
ON per3.id = xxx.person_id
AND ort3.id = per3.ort_id
>
> Nun wird mir für diese Zeilen "1064: You have an error ..." angezeigt. Habe versucht, den Fehler durch Klammer setzen zu beheben, Fehler bleibt.
>
> Ich habe erstmalig probiert, mit dem join zwei Tabellen ansprechen. Geht das?
ja, selbstverständlich. Nur muss man auch zweimal das Schlüsselwort "JOIN" verwenden, siehe Artikel [Fortgeschrittene JOIN-Techniken](http://wiki.selfhtml.org/wiki/Artikel:DBMS_und_SQL/Fortgeschrittene_Jointechniken#Mehrere_Tabellen_mit_JOIN_verkn.C3.BCpfen_-_unterschiedliche_Joinspalten).
Freundliche Grüße
Vinzenz
Hallo, Vinzenz,
LEFT JOIN "personen" per3
,"orte" ort3
ON per3.id = xxx.person_id
AND ort3.id = per3.ort_id
> > Ich habe erstmalig probiert, mit dem join zwei Tabellen ansprechen. Geht das?
> ja, selbstverständlich. Nur muss man auch zweimal das Schlüsselwort "JOIN" verwenden, siehe Artikel [Fortgeschrittene JOIN-Techniken](http://wiki.selfhtml.org/wiki/Artikel:DBMS_und_SQL/Fortgeschrittene_Jointechniken#Mehrere_Tabellen_mit_JOIN_verkn.C3.BCpfen_-_unterschiedliche_Joinspalten).
Also für \_jede\_ Tabelle einmal das Schlüsselwort JOIN. Ich wollte es synonym gebrauchen zu
~~~sql
FROM "personen" per1
,"orte" ort1
WHERE per1.id = xxx.person_id
AND ort1.id = per1.ort_id
da kann man mehrere Tabellen mit nur einmal FROM ansprechen.
Geht also nicht.
Gruß, Gast
Das ist ja auch irgendwie ein JOIN. Nur sieht man nicht so deutlich was da passiert.
Das ist ja auch irgendwie ein JOIN. Nur sieht man nicht so deutlich was da passiert.
Das ist nicht irgendwie ein Join. Das ist ein Join - ein impliziter Join.
Hallo,
mein Beispiel war, dass ein Personensatz ggf. auf einen zweiten Personensatz hinweist, den ich auch benötige. Beispiel wäre die Adresse einer Filiale, zu der ich immer den Hauptsitz brauche.
Das Verfahren mit JOIN ist doch recht umständlich. Wenn ich die ID beider Sätze im Voraus kennen würde, ginge es so:
WHERE per1.id = '4711' OR per1.id = '0815'
Ich kenne aber nur 4711, der auf 0815 hinweist. Gibt es einen Trick, als ersten Satz des SELECT die 4711 zu bekommen und - falls vorhanden - als zweiten Satz den referenzierten?
Gruß, Gast
Hallo,
mein Beispiel war, dass ein Personensatz ggf. auf einen zweiten Personensatz hinweist, den ich auch benötige. Beispiel wäre die Adresse einer Filiale, zu der ich immer den Hauptsitz brauche.
wenn Du keine Tabellen mit Beispieldaten, dem gewünschten Ergebnis und der Begründung dafür lieferst, dann ist das wie im Dunklen umhertappen. Sowas macht mir keinen Spass.
Vielleicht suchst Du ja Subqueries, vielleicht willst Du auch überhaupt keine OUTER JOINS, dein Text oben hört sich danach an :-)
Freundliche Grüße
Vinzenz
Hallo, Vinzenz,
wenn Du keine Tabellen mit Beispieldaten, dem gewünschten Ergebnis und der Begründung dafür lieferst, dann ist das wie im Dunklen umhertappen. Sowas macht mir keinen Spass.
Es handelt sich um einen Monster-Select, der jetzt schon acht JOINS hat. Da wird der Ort dazugeholt, verwendete Sprachen und Übersetzungstabellen. Ich versuche, das Teilproblem herauszulösen:
id name ort_id ueber_id
----- --------------- ------- --------
0815 Aldi-Zentrale 13556 NULL
4711 Aldi Frankfurt 17342 0815
4712 Mustermann 16344 NULL
Mit einem (und nur einem) SELECT greife ich id=4711 und möchte 0815 als zweiten Datensatz dazugeliefert bekommen. Wenn ich id=4712 greife, kommt nur ein Datensatz.
Wenn ich die Zentrale mit einem JOIN dazuhole, muss die Spalte name ein zweites Mal benannt sein, etwa name2. Dadurch kann ich aber im folgenden PHP nicht dieselbe Routine für Filiale und Zentrale nutzen, das möchte ich aber gerne.
Vielleicht suchst Du ja Subqueries, vielleicht willst Du auch überhaupt keine OUTER JOINS, dein Text oben hört sich danach an :-)
Ist das mit einem Subquery zu machen?
SELECT per1.name, ...
FROM personen per1
WHERE per1.id = '4711' OR per1.id = (SELECT per2.id FROM personen per2 WHERE per2.id = per1.ueber_id)
Nee *überleg*
WHERE per1.id = '4711' OR per1.id = per1.ueber_id
Nee, auch nicht. Hast du verstanden, wo mein Problem ist?
Gruß, Gast
Hallo,
Es handelt sich um einen Monster-Select, der jetzt schon acht JOINS hat. Da wird der Ort dazugeholt, verwendete Sprachen und Übersetzungstabellen. Ich versuche, das Teilproblem herauszulösen:
id name ort_id ueber_id
0815 Aldi-Zentrale 13556 NULL
4711 Aldi Frankfurt 17342 0815
4712 Mustermann 16344 NULL
das sieht nach einer hierarchischen Beziehung aus. Hierarchische Beziehungen bereiten in relationalen Datenbanken durchaus Bauchgrimmen :-)
Wenn es nur zwei Ebenen gibt, dann könntest Du den zweiten Datensatz per Selfjoin bekommen. Wie ich im Dir bereits bekannten Artikel schreibe, skalieren Selfjoins nicht besonders gut:
Idee 1:
SELECT
id,
name,
ort_id,
ueber_id
FROM
tabelle
WHERE
id = 4711
liefert Dir die Aldi-Filiale in Frankfurt
Der Selfjoin:
SELECT
t1.id,
t1.name,
t1.ort_id,
t1.ueber_id
FROM
tabelle t1
INNER JOIN
tabelle t2
ON
t1.id = t2.ueber_id
WHERE
t2.id = 4711
liefert Dir die zugehörige Aldi-Zentrale zur Filiale in Frankfurt.
Die UNION beider Abfragen liefert Dir die beiden gewünschten Datensätze:
SELECT
id,
name,
ort_id,
ueber_id
FROM
tabelle
WHERE
id = 4711
UNION ALL
SELECT
t1.id,
t1.name,
t1.ort_id,
t1.ueber_id
FROM
tabelle t1
INNER JOIN
tabelle t2
ON
t1.id = t2.ueber_id
WHERE
t2.id = 4711
liefert die beiden gewünschten Datensätze
Alternativ könntest Du mit einer Subquery arbeiten:
SELECT -- Gib mir
id, -- den Datensatz
name,
ort_id,
ueber_id
FROM
tabelle
WHERE
id = 4711 -- bei dem die id 4711 ist
OR -- oder deren
id IN ( -- id in der
SELECT -- Liste der
t2.ueber_id -- Werte der ueber_ids
FROM -- aus
tabelle t2 -- der gleichen Tabelle enthalten ist
WHERE -- wobei nur die Datensätze betrachtet werden
t2.id = 4711 -- deren id-Wert 4711 ist
)
Sobald Du mehr als zwei Ebenen betrachten musst, dann solltest Du Dein Konzept der einfachen Adjazenzliste überdenken. Vielleicht käme das Nested-Set-Modell in Frage, vielleicht auch der Closure-Tree.
Das hängt durchaus von Deinen Daten und den typischen Operationen auf diesen Daten ab.
Freundliche Grüße
Vinzenz
Hallo, Vinzenz,
ganz herzlichen Dank für deine Mühe.
Ich habe in der Zwischenzeit mit einem Subquery rumprobiert. Aber der UNION ALL wäre eine Alternative.
Gruß, Gast