Verwendung:
SELECT * FROM t1 FULL OUTER JOIN t2 ON t1.id = t2.id;
Sie kann wie folgt nachgebildet werden:
SELECT t1.*, t2.*
FROM (SELECT * FROM t1 UNION SELECT name FROM t2) tmp
LEFT JOIN t1 ON t1.id = tmp.id
LEFT JOIN t2 ON t2.id = tmp.id;
Die Verwendung einer UNION- oder UNION ALL-Antwort deckt nicht den Grenzfall ab, in dem die Basistabellen doppelte Einträge haben.
Erläuterung:
Es gibt einen Grenzfall, den eine UNION oder UNION ALL nicht abdecken kann. Wir können dies nicht mit MySQL testen, da es keine Full Outer Joins unterstützt, aber wir können dies mit einer Datenbank veranschaulichen, die es unterstützt:
WITH cte_t1 AS
(
SELECT 1 AS id1
UNION ALL SELECT 2
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 6
),
cte_t2 AS
(
SELECT 3 AS id2
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 6
)
SELECT * FROM cte_t1 t1 FULL OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2;
This gives us this answer:
id1 id2
1 NULL
2 NULL
NULL 3
NULL 4
5 5
6 6
6 6
6 6
6 6
Die UNION-Lösung:
SELECT * FROM cte_t1 t1 LEFT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2
UNION
SELECT * FROM cte_t1 t1 RIGHT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2
Gibt eine falsche Antwort:
id1 id2
NULL 3
NULL 4
1 NULL
2 NULL
5 5
6 6
Die UNION ALL-Lösung:
SELECT * FROM cte_t1 t1 LEFT OUTER join cte_t2 t2 ON t1.id1 = t2.id2
UNION ALL
SELECT * FROM cte_t1 t1 RIGHT OUTER JOIN cte_t2 t2 ON t1.id1 = t2.id2
ist ebenfalls falsch.
id1 id2
1 NULL
2 NULL
5 5
6 6
6 6
6 6
6 6
NULL 3
NULL 4
5 5
6 6
6 6
6 6
6 6
Während diese Abfrage:
SELECT t1.*, t2.*
FROM (SELECT * FROM t1 UNION SELECT name FROM t2) tmp
LEFT JOIN t1 ON t1.id = tmp.id
LEFT JOIN t2 ON t2.id = tmp.id;
Gibt das Folgende an:
id1 id2
1 NULL
2 NULL
NULL 3
NULL 4
5 5
6 6
6 6
6 6
6 6
Die Reihenfolge ist anders, aber ansonsten stimmt sie mit der richtigen Antwort überein.
4 Stimmen
Mögliche Duplikate von MySQL Voller äußerer Join Syntaxfehler
4 Stimmen
Auf diese Frage gibt es bessere Antworten
6 Stimmen
Achten Sie auf die Antworten hier. Der SQL-Standard besagt, dass full join on inner join on rows union all unmatched left table rows extended by nulls union all right table rows extended by nulls ist. Die meisten Antworten hier sind falsch (siehe die Kommentare) & die, die nicht falsch sind, behandeln den allgemeinen Fall nicht. Auch wenn es viele (ungerechtfertigte) Upvotes gibt. (Siehe meine Antwort.)
0 Stimmen
Wie sieht es aus, wenn Sie versuchen, nach nicht primären Schlüsseln/gruppierten Spalten zu verknüpfen? z. B. habe ich eine Abfrage der Verkäufe pro Staat "Staat", "Verkäufe" und eine andere der Ausgaben pro Staat "Staat", "Ausgaben", beide Abfragen verwenden group by("Staat"). Wenn ich die Vereinigung zwischen den linken und rechten Verknüpfungen zwischen zwei Abfragen mache, erhalte ich ein paar Zeilen mit Verkäufen, aber keine Ausgaben, ein paar mehr mit Ausgaben, aber keine Verkäufe, alles richtig bis zu diesem Punkt, aber ich erhalte auch ein paar mit sowohl Verkäufe und Ausgaben und eine wiederholte Spalte "Staat"... nicht viel von einem Problem, aber fühlt sich nicht richtig an...
1 Stimmen
@JairoLozano Constraints sind für die Abfrage nicht erforderlich. Obwohl, wenn Constraints gelten, liefern zusätzliche Abfragen die gewünschte Antwort, die sonst nicht gegeben würde. Constraints haben keinen Einfluss darauf, was ein vollständiger Join on für gegebene Argumente zurückgibt. Das von Ihnen beschriebene Problem besteht darin, dass die von Ihnen geschriebene Abfrage die falsche Abfrage ist. (Vermutlich handelt es sich um den häufigen Fehler, dass Leute einige Joins, die möglicherweise jeweils einen anderen Schlüssel beinhalten, von einigen Unterabfragen, die möglicherweise jeweils einen Join und/oder eine Aggregation beinhalten, wollen, aber fälschlicherweise versuchen, den gesamten Join und dann die gesamte Aggregation durchzuführen oder über frühere Aggregationen zu aggregieren).
4 Stimmen
Alle Antworten, die UNION anstelle von UNION ALL verwenden, sind falsch. Alle Antworten mit Unterabfragen oder 3 vereinigten Selects sind ineffizient. Richtige Antworten führen einen Union All eines Left Join mit einem Select aus der zweiten Tabelle mit einem Where Not Exists in der ersten Tabelle durch (oder den entsprechenden Outer Join + Where = NULL Bedingung).
0 Stimmen
Einige der Inhalte hier sind Gegenstand der Metafrage Wie sollte ich mit einer falschen Antwort umgehen, die akzeptiert wird und viele positive Bewertungen hat? .