template
Index :: PHP/MySQL :: SQL: Tabellenübergreifende Abfragen (JOIN)
In den meisten Fällen wird innerhalb einer Query eine einzelne Tabelle angesprochen.
Hier werden die Namen aller Personen (Tabelle person) gesucht, die im Bereich 'Verkauf' arbeiten:
person |
  | Feldname | Typ |   |
0 | PID | int | PersonenID |
1 | Vname | varchar[24] | Vorname |
2 | Nname | varchar[24] | Nachname |
3 | Bereich | varchar[32] | Arbeitsbereich |
SELECT Nname
FROM person
WHERE Bereich='Verkauf'
ORDER BY Nname
Will man wissen, welche Personen in den einzelnen Bereichen arbeiten, könnte die Query folgendermaßen aussehen (die Bereiche sollen alphabetisch sortiert sein):
SELECT Bereich,Nname
FROM person
ORDER BY Bereich,Nname
Um die Stärken relationaler Datenbanken auszuschöpfen, lagert man redundante Informationen gerne in separate Tabellen aus und benutzt Verweise (bzw. IDs oder ENUMs). Bei diesem Vorgehen - Normalisierung genannt - werden komplexe Tabellen in kleinere aufgesplittet, wodurch die Datenbank strukturierter und letztendlich besser pflegbar wird.
In obigem Fall wäre das Feld bereich solch ein Kandidat, weil es sich um einen häufig wiederkehrenden Textausdruck handelt. Daher könnte man eine Tabelle bereich anlegen, in der alle Bereiche nebst einer ID (hier: BID) aufgelistet sind. In der Personen-Tabelle genügt nun ein int als Verweis auf den Bereich.
bereich |
  | Feldname | Typ |   |
0 | BID | int | BereichsID |
1 | Bereich | varchar[24] | Arbeitsbereich |
person |
  | Feldname | Typ |   |
0 | PID | int | PersonenID |
1 | Vname | varchar[24] | Vorname |
2 | Nname | varchar[24] | Nachname |
3 | BID | int | BereichsID |
Angenommen, der Bereich 'Verkauf' hätte die ID 3, dann würde man so alle Verkäufer suchen:
SELECT Nname
FROM person
WHERE BID=3
ORDER BY Nname
Will man wieder wissen, welche Personen in den einzelnen Bereichen arbeiten, müssen wir auf 2 Tabellen zugreifen: auf person, um den Personennamen zu sortieren/zeigen und auf bereich, um den Bereich zu sortieren/zeigen. Die Tabellen müssen (über das Feld BID) sozusagen synchronisiert werden, was mit JOIN erreicht werden kann:
SELECT Bereich,Nname
FROM person
LEFT JOIN bereich ON bereich.BID=person.BID
ORDER BY Bereich,Nname
Es wurde ein LEFT JOIN verwendet, damit im Ergebnis garantiert alle Datensätze der linken Tabelle (person) auftauchen.
Damit werden also selbst solche Personen gezeigt, bei denen die ON-Bedingung (bereich.BID=person.BID) nicht zutrifft - weil z.B. bei Aushilfskräften ohne speziellen Arbeitsbereich im Feld person.BID eine 0 steht, für die es in der Bereichs-Tabelle keine Entsprechung gibt. In diesen Fällen ist das Bereich-Element des gelieferten Arrays leer, und aufgrund der Sortierung stehen die Aushilfskräfte am Anfang der Ergebnisliste.
template |
|