Die Antwort, die Pablo Santa Cruz ist korrekt; falls jedoch jemand auf diese Seite gestoßen ist und mehr Klarheit wünscht, finden Sie hier eine detaillierte Aufschlüsselung.
Beispieltabellen
Angenommen, wir haben die folgenden Tabellen:
-- t1
id name
1 Tim
2 Marta
-- t2
id name
1 Tim
3 Katarina
Inner Joins
Eine innere Verbindung, etwa so:
SELECT *
FROM `t1`
INNER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
würde uns nur Datensätze liefern, die in beiden Tabellen erscheinen, etwa so:
1 Tim 1 Tim
Innere Verknüpfungen haben keine Richtung (wie links oder rechts), da sie explizit bidirektional sind - wir benötigen eine Übereinstimmung auf beiden Seiten.
Äußere Verbindungen
Outer-Joins hingegen dienen dazu, Datensätze zu finden, für die es in der anderen Tabelle möglicherweise keine Übereinstimmung gibt. Als solche müssen Sie angeben welche Seite der Verknüpfung darf einen fehlenden Datensatz enthalten.
LEFT JOIN
y RIGHT JOIN
sind Kurzformen für LEFT OUTER JOIN
y RIGHT OUTER JOIN
Ich werde im Folgenden ihre vollständigen Namen verwenden, um das Konzept der äußeren Joins gegenüber den inneren Joins zu verdeutlichen.
Linke äußere Verbindung
Eine linke äußere Verknüpfung, etwa so:
SELECT *
FROM `t1`
LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
...würde uns alle Datensätze aus der linken Tabelle liefern, unabhängig davon, ob sie eine Übereinstimmung in der rechten Tabelle haben oder nicht, etwa so:
1 Tim 1 Tim
2 Marta NULL NULL
Rechter äußerer Join
Eine rechte äußere Verknüpfung, etwa so:
SELECT *
FROM `t1`
RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
...würde uns alle Datensätze aus der rechten Tabelle liefern, unabhängig davon, ob sie eine Übereinstimmung in der linken Tabelle haben oder nicht, etwa so:
1 Tim 1 Tim
NULL NULL 3 Katarina
Vollständiger äußerer Join
Eine vollständige äußere Verknüpfung würde uns alle Datensätze aus beiden Tabellen liefern, unabhängig davon, ob sie eine Übereinstimmung in der anderen Tabelle haben oder nicht, mit NULLs auf beiden Seiten, wenn es keine Übereinstimmung gibt. Das Ergebnis würde wie folgt aussehen:
1 Tim 1 Tim
2 Marta NULL NULL
NULL NULL 3 Katarina
Wie Pablo Santa Cruz jedoch feststellte, unterstützt MySQL dies nicht. Wir können es emulieren, indem wir eine UNION aus einem linken Join und einem rechten Join machen, etwa so:
SELECT *
FROM `t1`
LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`
UNION
SELECT *
FROM `t1`
RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`;
Sie können sich eine UNION
bedeutet: "Führen Sie beide Abfragen aus und stapeln Sie dann die Ergebnisse übereinander"; einige der Zeilen stammen aus der ersten Abfrage und einige aus der zweiten.
Es ist zu beachten, dass ein UNION
in MySQL werden exakte Duplikate eliminiert: Tim würde hier in beiden Abfragen erscheinen, aber das Ergebnis der UNION
wird er nur einmal aufgeführt. Mein Kollege, der Datenbankguru, ist der Meinung, dass man sich auf dieses Verhalten nicht verlassen sollte. Um es also deutlicher zu machen, könnten wir eine WHERE
Klausel in die zweite Abfrage einfügen:
SELECT *
FROM `t1`
LEFT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`
UNION
SELECT *
FROM `t1`
RIGHT OUTER JOIN `t2` ON `t1`.`id` = `t2`.`id`
WHERE `t1`.`id` IS NULL;
Andererseits, wenn Sie gesucht um aus irgendeinem Grund Duplikate zu sehen, können Sie UNION ALL
.
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? .