Problem mit JOIN
Yadgar
- datenbank
High!
Folgendes Problem: Zwei Tabellen: instrumentenhersteller (mit den Spalten ID und Name), instrumentenmodelle (mit den Spalten ID, Hersteller, Modell, Typ).
Da die Spalte "Typ" in "instrumentenmodelle" sich auf die Spalte "instrumente" bezieht, es in den konkreten Rohdaten aber durchaus vorkommen kann, dass nur das Instrument (z. B. elektronische Orgel, Synthesizer etc.) bekannt ist, nicht aber Hersteller und Modellbezeichnung, stehen in "instrumentenmodelle" unter "Modell" auch die Bezeichnungen aus "instrument", "Hersteller" hat dann logischerweise den Wert 0.
Wenn ich jetzt versuche, Modell und Hersteller (sofern vorhanden) in einer Tabelle anzeigen zu lassen:
SELECT instrumentenhersteller.Name, instrumentenmodelle.Modell FROM instrumentenmodelle LEFT JOIN instrumentenhersteller ON instrumentenmodelle.Hersteller = instrumentenhersteller.ID OR instrumentenmodelle.Hersteller = 0 ORDER BY Hersteller, Modell
bekomme ich für die Tupel, wo "Hersteller" 0 ist, eine Kreuzverknüpfung angezeigt, die übrigen Tupel jedoch nur einmal. Das sieht so aus:
Name Modell
Korg elektronische Orgel
Yamaha elektronische Orgel
Hammond elektronische Orgel
Yamaha elektronische Orgel
Korg elektronische Orgel
Hammond elektronische Orgel
Yamaha Electone C-55N
Yamaha SY-55
Hammond B3
Richtig wäre es so:
Name Modell
elektronische Orgel
elektronische Orgel
Yamaha Electone C-55N
Yamaha SY-55
Hammond B3
Wie bekomme ich das hin?
Bis bald im Khyberspace!
Yadgar
Moin!
Da die Spalte "Typ" in "instrumentenmodelle" sich auf die Spalte "instrumente" bezieht, es in den konkreten Rohdaten aber durchaus vorkommen kann, dass nur das Instrument (z. B. elektronische Orgel, Synthesizer etc.) bekannt ist, nicht aber Hersteller und Modellbezeichnung, stehen in "instrumentenmodelle" unter "Modell" auch die Bezeichnungen aus "instrument", "Hersteller" hat dann logischerweise den Wert 0.
Logisch wäre, den Wert NULL einzutragen, nicht 0.
SELECT instrumentenhersteller.Name, instrumentenmodelle.Modell FROM instrumentenmodelle LEFT JOIN instrumentenhersteller ON instrumentenmodelle.Hersteller = instrumentenhersteller.ID OR instrumentenmodelle.Hersteller = 0 ORDER BY Hersteller, Modell
>
> bekomme ich für die Tupel, wo "Hersteller" 0 ist, eine Kreuzverknüpfung angezeigt, die übrigen Tupel jedoch nur einmal.
Das liegt an deiner Join-Bedingung. Du joinst mit allen Werten der linken Tabelle, wenn rechts eine 0 eingetragen ist.
Eigentlich willst du für "nicht bekannter Wert" NULL in die Tabelle eintragen und deine Abfrage als OUTER JOIN gestalten, wobei LEFT oder RIGHT OUTER JOIN passen könnte, jenachdem, ob deine NULL-Werte-Tabelle links oder rechts im Join steht.
Ein OUTER JOIN nimmt alle Tabelleneinträge der ersten (links oder rechts stehenden) Tabelle und verknüpft dann, wenn ein Eintrag in der zweiten Tabelle gefunden wurde, diesen. Bei NULL wird kein Wert gefunden, die Spalten der zweiten Tabelle daher mit NULL als Lückenfüllern aufgefüllt und zurückgegeben.
Dein User-Interface muss noch entsprechend angepasst werden dahingehend, dass man "kenn ich nicht/unbekannt" auswählen kann, und in die DB dann NULL als Wert eingetragen wird. Wenn du bislang die 0 als Wert für diesen Fall genommen hast, die Wahlmöglichkeit aber schon existiert, sollte sich die Anpassung auf das Wandeln der 0 in NULL an geeigneter Stelle beschränken. Die Ausgabe von NULL-Werten erfordert dann evtl. auch noch etwas optisches Anpassen.
- Sven Rautenberg
High!
Logisch wäre, den Wert NULL einzutragen, nicht 0.
Ich habe die Abfrage mit PHPMyAdmin getestet - und da wird bei Schlüsselverweisen auf nicht vorhandene Spalteneinträge nicht zwischen NULL und 0 unterschieden, in den angezeigten Ergebnistabellen steht dann einfach 0...
Mit LEFT OUTER JOIN und Prüfung auf NULL hat es aber funktioniert - danke für den Hinweis!
Bis bald im Khyberspace!
Yadgar