Hallo zusammen,
ich habe gerade einen komischen Effekt bei einem LEFT OUTER JOIN in postgres festgestellt. Leider hab ich im Moment keine andere Datenbank zur Hand, an der ich dieses Verhalten ausprobieren könnte.
Sinn eines LEFT OUTER JOIN ist es ja, in der Ergebnistabelle für jede Zeile der linken Tabelle mindestens einen Eintrag zu bekommen, auch wenn in der rechten Zeile keine JOIN-Bedingung zugetroffen hat. Das funktioniert auch, solange ich keine WHERE-Bedingung mehr einbaue. Nehmen wir an ich habe 2 Tabellen genannt Vater und Sohn mit folgendem Aussehen:
Vater:
id Name
---------
1 Anton
2 Horst
3 Peter
Sohn:
Name Vater_id
-----------------------
Helmut 2
Paul 3
Nur Horst und Peter haben also Söhne, Anton nicht. Ein LEFT OUTER JOIN würde dann zu folgendem Ergebnis führen:
SELECT * FROM Vater LEFT OUTER JOIN Sohn ON (Vater.id = Sohn.Vater_id);
id Name Name Vater_id
---------
1 Anton
2 Horst Helmut 2
3 Peter Paul 3
d.h. Anton wird angezeigt, aber eben ohne Sohn, so wie es sein soll. Wird die Abfrage nun um eine WHERE-Bedingung erweitert, so funktioniert dies nicht mehr:
SELECT * FROM Vater LEFT OUTER JOIN Sohn ON (Vater.id = Sohn.Vater_id) WHERE Vater.id <3;
Die die Vater.id soll also kleiner 3 sein, d.h. nur Anton und Horst sollen aufgelistet werden.
Die Abfrage ergibt jedoch:
id Name Name Vater_id
---------
2 Horst Helmut 2
Anton ist also aus dem Ergebnis verschwunden, obwohl er eine id < 3 hat.
Ist das ein Standardkonformes Verhalten??? Ich kann mich da echt nimmer dran erinnern. Zu umgehen ist das Ganze mit einem Subselect wie z.B.:
SELECT * FROM (SELECT * FROM Vater WHERE id < 3) AS temp LEFT OUTER JOIN Sohn ON (temp.id = Sohn.Vater_id);
Das Kann bei größeren Anfragen jedoch leicht vollkommen unüberschaubar und fast schon unmöglich werden. Deshalb eben die Frage: Ist dieses Verhalten Standardkonform, woran liegt das und gibt es einen schlaueren Weg?
Viele Grüße,
Bierstuebl