template

Index :: PHP/MySQL :: SQL: Tabellenübergreifende Abfragen (JOIN)


Einfache Queries

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
 FeldnameTyp 
0PIDintPersonenID
1Vnamevarchar[24]Vorname
2Nnamevarchar[24]Nachname
3Bereichvarchar[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

Queries mit JOIN

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
 FeldnameTyp 
0BIDintBereichsID
1Bereichvarchar[24]Arbeitsbereich

person
 FeldnameTyp 
0PIDintPersonenID
1Vnamevarchar[24]Vorname
2Nnamevarchar[24]Nachname
3BIDintBereichsID

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.

Index :: PHP/MySQL


template