2010-03-05 16 views
32
SELECT airline, airports.icao_code, continent, country, province, city, website 

FROM airlines 
FULL OUTER JOIN airports ON airlines.iaco_code = airports.iaco_code 
FULL OUTER JOIN cities ON airports.city_id = cities.city_id 
FULL OUTER JOIN provinces ON cities.province_id = provinces.province_id 
FULL OUTER JOIN countries ON cities.country_id = countries.country_id 
FULL OUTER JOIN continents ON countries.continent_id = continents.continent_id 

Er sagt, dassWarum meldet MySQL bei FULL OUTER JOIN einen Syntaxfehler?

Sie haben einen Fehler in Ihrer SQL-Syntax; Sie in der Bedienungsanleitung zu Ihrem MySQL-Server-Version für den richtigen Syntax entspricht verwenden in der Nähe von ‚Außen airports auf airlines.iaco_code = airports.iaco_code vollständige äußere Join‘

Die Syntax sieht mir richtig in Zeile 4. Ich habe vorher noch nie viele Joins gemacht, aber ich brauche diese Spalten in einer Tabelle, die von verschiedenen IDs referenziert wird.

+0

Es gibt keine 'FULL OUTER JOIN' Syntax: http://dev.mysql.com/doc/refman/5.0/en/join.html –

Antwort

61

In MySQL gibt es keine FULL OUTER JOIN. Siehe 7.2.12. Outer Join Simplification und 12.2.8.1. JOIN Syntax:

Sie emulieren kann FULL OUTER JOIN mit UNION (von MySQL 4.0.0 auf):

mit zwei Tabellen T1, T2:

SELECT * FROM t1 
LEFT JOIN t2 ON t1.id = t2.id 
UNION 
SELECT * FROM t1 
RIGHT JOIN t2 ON t1.id = t2.id 

mit drei Tabellen t1, t2, t3:

SELECT * FROM t1 
LEFT JOIN t2 ON t1.id = t2.id 
LEFT JOIN t3 ON t2.id = t3.id 
UNION 
SELECT * FROM t1 
RIGHT JOIN t2 ON t1.id = t2.id 
LEFT JOIN t3 ON t2.id = t3.id 
UNION 
SELECT * FROM t1 
RIGHT JOIN t2 ON t1.id = t2.id 
RIGHT JOIN t3 ON t2.id = t3.id 
+0

Gibt es ein Tutorial Sie schließt sich empfehlen würde? –

+3

Ihre Antwort ist nicht wirklich korrekt, siehe [Xerrach's Antwort] (http://stackoverflow.com/a/3357262/52499), oder [dieser Kommentar] (http://stackoverflow.com/questions/4796872/full-outer -join-in-mysql # Kommentar21960067_4796911). –

+0

@Cletus, ich bekomme immer 'Duplicate column name' Fehler in der PK-Spalte, die sie teilen ... – Awena

11

Die Antwort von Cletus ist nicht ganz richtig. UNION wird doppelte Datensätze entfernen, die eine FULL OUTER JOIN enthalten würde. Wenn Sie Duplikate etwas verwenden müssen wie:

SELECT * FROM t1 
LEFT JOIN t2 ON t1.id = t2.id 
LEFT JOIN t3 ON t2.id = t3.id 
LEFT JOIN t4 ON t3.id = t4.id 
UNION ALL 
SELECT * FROM t1 
RIGHT JOIN t2 ON t1.id = t2.id 
LEFT JOIN t3 ON t2.id = t3.id 
LEFT JOIN t4 ON t3.id = t4.id 
WHERE t1.id IS NULL 
UNION ALL 
SELECT * FROM t1 
RIGHT JOIN t2 ON t1.id = t2.id 
RIGHT JOIN t3 ON t2.id = t3.id 
LEFT JOIN t4 ON t3.id = t4.id 
WHERE t2.id IS NULL 
UNION ALL 
SELECT * FROM t1 
RIGHT JOIN t2 ON t1.id = t2.id 
RIGHT JOIN t3 ON t2.id = t3.id 
RIGHT JOIN t4 ON t3.id = t4.id 
WHERE t3.id IS NULL; 
+1

Beachten Sie, dass - wenn Sie ausreichend pedantisch und theoretisch sind - dies auch keine perfekte Lösung ist. Dieser Ansatz (der "UNION ALL" verwendet, aber prüft, ob eine Spalte in einer der 'JOIN'ed-Tabellen' NULL 'ist, um zu identifizieren, dass sie nicht mit irgendwelchen Zeilen in den anderen Tabellen übereinstimmen) beruht auf den tatsächlich vorhandenen Tabellen mindestens eine "NOT NULL" -Spalte. Wenn es keine Spalte gibt, die garantiert nicht * tatsächlich * ein 'NULL 'enthält, wird diese Methode nicht funktionieren. –

+0

@MarkAmery: Sie heben einen guten Punkt. Damit der Anti-Join korrekt funktioniert, muss das Prädikat in der WHERE-Klausel auf eine Spalte oder einen Ausdruck verweisen, den wir * kennen * (also * garantiert *), wenn eine übereinstimmende Zeile gefunden wird. Im speziellen Fall des Join-Prädikats, das einen ** Gleichheit ** -Vergleich verwendet, garantiert dieser Gleichheitsvergleich, dass der Wert dieser Spalte für übereinstimmende Zeilen nicht NULL ist. Es braucht keinen Gleichheitsvergleich, um uns diese Garantie zu geben.Wenn der Join NULL-Werte für "übereinstimmende" Zeilen zulässt, müssen wir einen Nicht-NULL-Ausdruck suchen/verwenden. – spencer7593

+1

@MarkAmery: Diese Abfrage basiert nicht auf den Tabellen mit einer NOT NULL-Spalte. Diese Abfrage basiert vielmehr auf dem Join-Prädikat (der Bedingung in der ON-Klausel), um einen Nicht-NULL-Wert für eine Spalte in einer "übereinstimmenden" Zeile zu garantieren. Dies beruht auf dem Verhalten des Operators * equality comparison * bei Verwendung mit NULL-Werten. (Wir wissen, dass 'foo = NULL' nicht TRUE zurückgibt, auch wenn' foo IS NULL' ist.) – spencer7593

0

Ich habe gerade einen Trick dafür:

(select 1 from DUAL) d 
LEFT OUTER JOIN t1 ON t1.id = t2.id 
LEFT OUTER JOIN t2 ON t1.id = t2.id 

der Punkt ist, dass die Abfrage von Dual einen Fix Punkt macht, und mysql kann Outer-Joins die 2 anderen Tabellen dazu

1

Ergänzen Sie einfach den Fall, wenn Sie FULL OUTER JOIN drei Tabellen t1, t2, t3 benötigen. Sie könnten t1, t2, t3 machen, der Reihe nach links verbindet die restlichen zwei Tabellen, dann die Vereinigung.

SELECT * FROM t1 
LEFT JOIN t2 ON t1.id = t2.id 
LEFT JOIN t3 ON t1.id = t3.id 
UNION 
SELECT * FROM t2 
LEFT JOIN t1 ON t2.id = t1.id 
LEFT JOIN t3 ON t2.id = t3.id 
UNION 
SELECT * FROM t3 
LEFT JOIN t1 ON t3.id = t1.id 
LEFT JOIN t2 ON t3.id = t2.id