Thomas Wiedmann http://www.twiedmann.de
• Sie befinden sich hier: Startseite > SQL-Backstube > ANSI JOIN vermischt mit Theta JOIN

Die SQL-Backstube

Bietet Rezepte, Lösungen und ausführliche Beispiele rund um gesundes SQL und zufriedene Datenbanken.

17.10.2010: ANSI JOIN vermischt mit Theta JOIN

SQL-92-Standard

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.


Problemstellung

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.


Getestet mit folgender Datenbank:

* IBM DB2 9.1
* MySQL 5.1.30
* ORACLE 10g 10.2 EE


Tabellen erzeugen

Listing 1:

  1. CREATE TABLE testtabelle (
  2. wert INT NOT NULL
  3. );

Testdaten einfügen

Listing 2:

  1. INSERT INTO testtabelle VALUES ( 1 );

Beispiel Theta JOIN oder "old school" JOIN

Listing 3:

  1. /**
  2. * DB2, MySQL, ORACLE
  3. */
  4. SELECT COUNT(*) AS anzahl
  5. FROM testtabelle t1,
  6. testtabelle t2,
  7. testtabelle t3
  8. WHERE t2.wert = t1.wert
  9. AND t3.wert = t1.wert
  10. AND t1.wert = 1;
  11. +--------+
  12. | anzahl |
  13. +--------+
  14. | 1 |
  15. +--------+
  16. 1 row in set (0.00 sec)

Beispiel SQL-92 ANSI JOIN

Listing 4:

  1. /**
  2. * DB2, MySQL, ORACLE
  3. */
  4. SELECT COUNT(*) AS anzahl
  5. FROM testtabelle t1
  6. JOIN testtabelle t2
  7. ON t2.wert = t1.wert
  8. JOIN testtabelle t3
  9. ON t3.wert = t1.wert
  10. WHERE t1.wert = 1;
  11. +--------+
  12. | anzahl |
  13. +--------+
  14. | 1 |
  15. +--------+
  16. 1 row in set (0.00 sec)

Theta und ANSI JOIN mischen - Teil 1

Listing 5:

  1. /**
  2. * DB2, MySQL, ORACLE
  3. */
  4. SELECT COUNT(*) AS anzahl
  5. FROM testtabelle t1, -- <== Theta (Komma-JOIN)
  6. testtabelle t2 -- <== Theta (Komma-JOIN)
  7. JOIN testtabelle t3 -- <== ANSI JOIN
  8. ON t3.wert = t1.wert -- <== ANSI JOIN
  9. WHERE t2.wert = t1.wert -- <== Theta (Komma-JOIN)
  10. AND t1.wert = 1;
  11. MySQL: ERROR 1054 (42S22): Unknown column 't1.wert' in 'on clause'
  12. IBM DB2: SQL0338N Eine Klausel ON, die einem Operator JOIN zugeordnet wurde oder die sich in einer Anweisung MERGE befindet, ist ungültig.
  13. 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.


Theta und ANSI JOIN mischen - Teil 2

Listing 6:

  1. /**
  2. * DB2, MySQL, ORACLE
  3. */
  4. SELECT COUNT(*) AS anzahl
  5. FROM testtabelle t1 -- <== ANSI JOIN
  6. JOIN testtabelle t2 -- <== ANSI JOIN
  7. ON t2.wert = t1.wert -- <== ANSI JOIN
  8. , testtabelle t3 -- <== Theta (Komma-JOIN)
  9. WHERE t3.wert = t1.wert -- <== Theta (Komma-JOIN)
  10. AND t1.wert = 1;
  11. +--------+
  12. | anzahl |
  13. +--------+
  14. | 1 |
  15. +--------+
  16. 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.


Nähere Erläuterungen im MySQL - Handbuch

[...] 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.[...]


Resumee

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.



Sitemap - Inhaltsverzeichnis

© 2002-2017 by Thomas Wiedmann : kontakt (at) twiedmann (punkt) de (Stand : 11.01.2015).