Moin! :)
Wenn ich habe:
SELECT blabla FROM table_right r
LEFT OUTER JOIN table_relation rel
ON (r.rightid = rel.rightid)
WHERE rel.leftid= 57
erhalte ich nur die Reihen, bei denen das Objekt 57 auch wirklich in der Relation vorkomt.
2 eigenschaft2 | 2 57
3 eigenschaft3 | 3 57
5 eigenschaft5 | 5 57
7 eigenschaft7 | 7 57
Werfe ich das WHERE raus, so erhalte ich auch Reihen, in denen andere Objekte referenziert werden
1 eigenschaft1 | 1 55
1 eigenschaft1 | 1 56
2 eigenschaft2 | 2 53
2 eigenschaft2 | 2 57
u.s.w.
Ok, das ist aber vollkommen OK - für mySQL. Du mußt dir die Reihenfolge klarmachen, in der das Ergebnis generiert wird:
Zuerst kommt ein SELECT auf die Eigenschaften. Ergebnis ist eine Tabelle mit allen Eigenschaften, die es gibt - also die ganze Tabelle.
Dann kommt der OUTER JOIN ON xxx. Der ordnet entsprechend der Bedingung jeder Zeile der ersten Tabelle alle passenden Zeilen aus der zweite Tabelle zu, und wenn es keine passende Zeile gibt, wird eine NULL-Zeile zugeordnet.
In der Ergebnistabelle steht dann das drin, was du nach Weglassen des WHERE erreicht hast. Und erst in _dieser_ Tabelle kommt WHERE zur Anwendung und filtert nur die Zeilen heraus, die der WHERE-Bedingung entsprechen. Deine Bedingung ist aber reichlich ungeeignet: Da du in der Tabelle (selbst wenn sie NULL-Werte für die Objekt-ID enthalten würde) nur nach Objekt-ID 57 suchst, wirst du niemals NULL-Werte finden.
Die Lösung liegt darin, die Selektion der richtigen Objekt-ID schon _vorher_ anzuwenden - im ON-Statement:
ON (r.rightid = rel.rightid) AND (rel.leftid = 57)
Die WHERE-Bedingung darf dann komplett entfallen (es sei denn, du suchst in der Ergebnistabelle nach was besonderem, beispielsweise einer bestimmten Eigenschaft).
Auf diese Weise wird die hinzuzufügende Tabelle beim Hinzufügen gefiltert. Einer Zeile aus der linken Tabelle wird nur dann eine Zeile der rechten Tabelle zugeordnet, wenn die ON-Bedingung stimmt: Wenn die Zeile der rechten Tabelle die richtige Eigenschafts-ID hat und die richtige Objekt-ID. (Anmerkung: "Linke" und "rechte" Tabelle bezieht sich auf die Position im SELECT-Statement, nicht auf deine Tabellenbezeichnung - ich finde "links" und "rechts" in der Tabellenbezeichnung auch etwas sehr unglücklich gewählt, weil es einen so gerne in die Denkfalle lockt, die linke Tabelle eben immer links ins SELECT zu schreiben und so weiter.)
Ich hab's nicht getestet, aber es sollte funktionieren.
- Sven Rautenberg