Eintrag-Details: LEFT JOIN zum Ermitteln fehlender Daten

29.01.2006

LEFT JOIN zum Ermitteln fehlender Daten

Folgendes Problem taucht immer wieder auf:

Zwei Tabellen sind prinzipiell durch ein Feld miteinander verbunden. Beispiel:

Adresse und Telefonnummer

Das ist immer dann sinnvoll, wenn zu einer Adresse mehrere Telefonnummern gehören können, beispielsweise wenn mehrere Durchwahlen zu einer Person möglich sind, oder eine zweite (Handy-)Nummer zur gleichen Adresse gespeichert werden soll.

[Mehr:]

Ein passender SQL-Dump zum Nachvollziehen des hier gezeigten Beispiels können Sie hier herunterladen.

Die Abfrage einer solchen Tabelle erfolgt dann üblicherweise mit einer normalen WHERE-Klausel:

select * from adressen, telefon
  where adressen.id = telefon.adr_id

Code herunterladen

In diesem Fall werden alle Adressen angezeigt, bei denen auch eine Telefonnummer gespeichert wurde. Der zugehörige Fremdschlüssel ist hier "telefon.adr_id".

Was ist jedoch, wenn (noch) nicht zu jeder Adresse eine Telefonnummer gespeichert wurde? Die obige Abfrage zeigt nicht die Adressen an, bei denen keine Telefonnummer existiert. In diesem Fall hilft eine Abfrage mit LEFT JOIN:

select * from adressen
  left join telefon
  on adressen.id = telefon.adr_id

Code herunterladen

Es werden nun alle Adressen angezeigt, auch wenn keine Telefonnummer in der Tabelle "telefon" vorhanden ist. Die Adressen ohne Telefonnummer enthalten im Ergebnis die Telefon-Felder ohne Inhalt (genauer: mit Inhalt NULL).

Möchte ich jetzt aber nur die Adressen erfahren, zu denen noch keine Telefonnummer gespeichert wurde, kann man sich dieses Ergebnis zu Nutze machen:

select * from adressen
  left join telefon
  on adressen.id = telefon.adr_id
  where isnull(telnum)

Code herunterladen

Der Trick ist recht einfach: Formulieren Sie für das Ergebnis eine WHERE-Klausel, bei dem sie auf isnull() abfragen. Das abgefragte Feld (hier: telnum) muss nur irgendein Feld sein, dass in der Telefon-Tabelle vorkommt und in der Feldliste der Abfrage steht.

In einer sauberen Abfrage sollten natürlich nur die Felder in der Feldliste stehen, die für das Ergebnis wirklich benötigt werden. Daher hier noch mal eine entsprechende Variante der letzten Abfrage:

select a.name, a.vorname, t.telnum 
  from adressen a
  left join telefon t
  on a.id = t.adr_id
  where isnull(telnum)

Code herunterladen

Hinweis: Diesen Text und die enthaltenen Beispielprogramme und Skripte dürfen Sie zum Erlernen der einzelnen Techniken und auch als Grundlage für Ihre eigenen Projekte auf eigene Gefahr kostenlos nutzen.

Bitte denken Sie daran, dass alle Texte und Quellcodes trotzdem urheberrechtlich geschützt sind. Eine direkte Weitergabe ist nur nach ausdrücklicher schriftlicher Genehmigung gestattet.

Permalink 29.01.2006 09:13:58, von Marian Email , 385 Wörter, 13932 mal angeschaut   German (DE) Kategorien: MySQL

Kommentare, Pingbacks:

Kommentar von: Artus [Besucher] · http://www.dragulsreich.de
hallo ich möchte aus einer tabelle zweimal ablesen aberich wei snicht sorecht wie ich das anstellen sol lhabe auch schon mal was vorbereitet ich dachte das es so geht aber irgendetwas haut nicht hin ^^

SELECT sum(spiel_feld.feld_ein_off+stutzplus.stutz_ein_off-stutzminus.stutz_ein_off) AS off,
sum(spiel_feld.feld_ein_deff+stutzplus.stutz_ein_deff-stutzminus.stutz_ein_deff) AS deff,
sum(spiel_feld.feld_ein_bauer+stutzplus.stutz_ein_bauer-stutzminus.stutz_ein_bauer) AS bauer,
sum(spiel_feld.feld_ein_pion+stutzplus.stutz_ein_pion-stutzminus.stutz_ein_pion) AS pion,
sum(spiel_feld.feld_ein_graf+stutzplus.stutz_ein_graf-stutzminus.stutz_ein_graf) AS graf
FROM spiel_feld
LEFT JOIN spiel_stutz stutzplus
ON spiel_stutz.stutz_an_x=spiel_feld.feld_x
AND spiel_stutz.stutz_an_y=spiel_feld.feld_y
LEFT JOIN spiel_stutz stutzminus
ON spiel_stutz.stutz_von_x=spiel_feld.feld_x
AND spiel_stutz.stutz_von_y=spiel_feld.feld_y
WHERE feld_x=15
AND feld_y =2";

ich danke wenn möglich für die hilfe ^^

gezeichnet Artus
Permalink 05.04.2008 @ 13:37

Kommentar schreiben:

Ihre E-Mail-Adresse wird nicht angezeigt.
Ihre URL wird angezeigt.
Antispam-Feld
Erlaubte XHTML Tags: <p, ul, ol, li, dl, dt, dd, address, blockquote, ins, del, span, bdo, br, em, strong, dfn, code, samp, kdb, var, cite, abbr, acronym, q, sub, sup, tt, i, b, big, small>
Optionen:
 
(Zeilenumbrüche werden zu <br />)
(Setze Cookies für Name, eMail & URL)

Der Blogger, der erstaunt auf den Bildschirm starrt

Werbung

Online-Kurse

  • Bequem PHP lernen bei freier Zeiteinteilung von zuhause
  • Der Onlinekurs den jeder versteht
  • www.lernpilot.de/wbt/

Konnte ich helfen?

mehr Werbung