Bietet Rezepte, Lösungen und ausführliche Beispiele rund um gesundes SQL und zufriedene Datenbanken.
Mit dem SQL-92 Standard wurde die Möglichkeit geschaffen, die JOIN Operatoren direkt im FROM Teil der SQL-Abfrage zu beschreiben. Der Vorteil ist - unter anderem - eine klare "visuelle" Trennung zwischen JOIN und WHERE.
Manchmal taucht auch unerwartet beim Projekt und Versions-Update der MySQL-Fehler "ERROR 1054 (42S22): Unknown column 'xyz' in 'on clause' " auf, obwohl diese Tabellenspalte ganz sicher vorhanden scheint. Probieren wir mal aus, was dies nun wieder zu bedeuten hat.
* IBM DB2 9.1
* MySQL 5.1.30
* ORACLE 10g 10.2 EE
CREATE TABLE testtabelle (
wert INT NOT NULL
);
INSERT INTO testtabelle VALUES ( 1 );
/**
* DB2, MySQL, ORACLE
*/
SELECT COUNT(*) AS anzahl
FROM testtabelle t1,
testtabelle t2,
testtabelle t3
WHERE t2.wert = t1.wert
AND t3.wert = t1.wert
AND t1.wert = 1;
+--------+
| anzahl |
+--------+
| 1 |
+--------+
1 row in set (0.00 sec)
/**
* DB2, MySQL, ORACLE
*/
SELECT COUNT(*) AS anzahl
FROM testtabelle t1
JOIN testtabelle t2
ON t2.wert = t1.wert
JOIN testtabelle t3
ON t3.wert = t1.wert
WHERE t1.wert = 1;
+--------+
| anzahl |
+--------+
| 1 |
+--------+
1 row in set (0.00 sec)
/**
* DB2, MySQL, ORACLE
*/
SELECT COUNT(*) AS anzahl
FROM testtabelle t1, -- <== Theta (Komma-JOIN)
testtabelle t2 -- <== Theta (Komma-JOIN)
JOIN testtabelle t3 -- <== ANSI JOIN
ON t3.wert = t1.wert -- <== ANSI JOIN
WHERE t2.wert = t1.wert -- <== Theta (Komma-JOIN)
AND t1.wert = 1;
MySQL: ERROR 1054 (42S22): Unknown column 't1.wert' in 'on clause'
IBM DB2: SQL0338N Eine Klausel ON, die einem Operator JOIN zugeordnet wurde oder die sich in einer Anweisung MERGE befindet, ist ungültig.
ORACLE: ORA-00904: "T1"."WERT": ungültiger Bezeichner
Werden die beiden JOIN Techniken so gemischt, dass der ANSI JOIN am Schluß kommt, kann der SQL nicht mehr ausgeführt werden. Alle drei getesteten Datenbanken erzeugen eine Fehlermeldung.
/**
* DB2, MySQL, ORACLE
*/
SELECT COUNT(*) AS anzahl
FROM testtabelle t1 -- <== ANSI JOIN
JOIN testtabelle t2 -- <== ANSI JOIN
ON t2.wert = t1.wert -- <== ANSI JOIN
, testtabelle t3 -- <== Theta (Komma-JOIN)
WHERE t3.wert = t1.wert -- <== Theta (Komma-JOIN)
AND t1.wert = 1;
+--------+
| anzahl |
+--------+
| 1 |
+--------+
1 row in set (0.00 sec)
Werden die beiden JOIN Techniken so gemischt, dass der ANSI JOIN gleich zu Beginn kommt, kann der SQL korrekt ausgeführt werden. Alle drei getesteten Datenbanken liefern das korrekte Ergebnis.
[...] Früher hatten der Kommaoperator (,) und JOIN dieselbe Rangstufe, d. h., der Join-Ausdruck t1, t2 JOIN t3 wurde als ((t1, t2) JOIN t3) interpretiert. Jetzt hat JOIN Vorrang vor dem Komma, d. h., der Ausdruck wird als (t1, (t2 JOIN t3)) ausgewertet. Diese Änderung betrifft Anweisungen, die eine ON-Klausel verwenden, denn diese Klausel kann nur Spalten in den Operanden des Joins referenzieren, und die Änderung in der Rangstufe wirkt sich darauf aus, wie interpretiert wird, was diese Operanden sind.[...]
SQL-92 ANSI JOIN bietet übersichtlichere Darstellung der Tabellenverknüpfungen einer SQL-Abfrage, als der ältere Theta oder "old-school" JOIN (in der WHERE Klausel). Daran mag sich nicht jeder gewöhnen. Das ist okay, aber beide JOIN Techniken zu vermischen, ist nicht empfehlenswert und erzeugt nur unübersichtliche Abfragen bzw. überraschende Fehler. Sollten zudem OUTER JOIN Bedingungen über mehrere Tabellen notwendig werden, läßt sich dies mit Abstand am einfachsten mit dem ANSI JOIN abbilden.