250 Stimmen

Wie kann ein LEFT OUTER JOIN mehr Datensätze zurückgeben, als in der linken Tabelle vorhanden sind?

Ich habe eine sehr einfache LEFT OUTER JOIN, um alle Ergebnisse aus der linken Tabelle und einige zusätzliche Informationen aus einer viel größeren Tabelle zurückzugeben. Die linke Tabelle enthält 4935 Datensätze, doch wenn ich einen LEFT OUTER JOIN mit einer zusätzlichen Tabelle durchführe, ist die Anzahl der Datensätze deutlich größer.

Soweit ich weiß, ist es ein absolutes Evangelium, dass ein LEFT OUTER JOIN alle Datensätze aus der linken Tabelle mit übereinstimmenden Datensätzen aus der rechten Tabelle und Nullwerten für alle Zeilen, die nicht übereinstimmen, zurückgibt, so dass es nach meinem Verständnis unmöglich sein sollte, mehr Zeilen zurückzugeben, als in der linken Tabelle vorhanden sind, aber es passiert trotzdem!

Es folgt eine SQL-Abfrage:

SELECT     SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID
FROM         SUSP.Susp_Visits LEFT OUTER JOIN
                      DATA.Dim_Member ON SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum

Vielleicht habe ich einen Fehler in der Syntax oder mein Verständnis von LEFT OUTER JOIN ist unvollständig, hoffentlich kann jemand erklären, wie dies auftreten könnte?

Nachtrag

Vielen Dank für die großartigen Antworten, mein Verständnis von LEFT OUTER JOINS ist jetzt viel besser, könnte jemand jedoch eine Möglichkeit vorschlagen, diese Abfrage geändert werden könnte, so dass ich nur so viele Datensätze zurückgegeben, wie in der linken Tabelle vorhanden?

Diese Abfrage dient lediglich dazu, einen Bericht zu erstellen, und die doppelten Treffer verwirren die Sache nur.

/Postskript

7 Stimmen

Um "so viele Datensätze zurückzubekommen, wie in der linken Tabelle vorhanden sind", müssen Sie angeben, welche Zeile auf der rechten Seite ausgewählt werden soll, wenn es mehrere Übereinstimmungen gibt.

1 Stimmen

Wie spezifizieren Sie dies? Ich möchte, dass der erste Treffer zurückgegeben wird.

1 Stimmen

Sie müssen definieren, was unter dem ersten Spiel zu verstehen ist. Wollen Sie den frühesten Datensatz, den mit der höchsten ID oder was?

260voto

Robin Day Punkte 97662

Der LEFT OUTER JOIN gibt alle Datensätze aus der LINKEN Tabelle zurück, die nach Möglichkeit mit der RECHTEN Tabelle verbunden sind.

Wenn es jedoch Übereinstimmungen gibt, werden alle übereinstimmenden Zeilen zurückgegeben, d. h. eine Zeile in LINKS, die mit zwei Zeilen in RECHTS übereinstimmt, wird als zwei Zeilen zurückgegeben, genau wie ein INNER JOIN.

EDIT: Als Antwort auf Ihre Bearbeitung habe ich mir Ihre Abfrage noch einmal angesehen, und es sieht so aus, als würden Sie nur Daten aus der Tabelle LEFT zurückgeben. Wenn Sie also nur Daten aus der Tabelle LEFT benötigen und für jede Zeile in der Tabelle LEFT nur eine Zeile zurückgegeben werden soll, brauchen Sie keinen JOIN durchzuführen und können einfach ein SELECT direkt aus der Tabelle LEFT ausführen.

5 Stimmen

Der Grund für die Verknüpfung mit der rechten Tabelle war, dass ich nur Datensätze von der linken Seite erhielt, wenn es mindestens einen Datensatz in der rechten Tabelle gab, aber vielen Dank für die Erklärung.

0 Stimmen

@JayWilde in diesem Fall sollten Sie Ihre Abfrage in eine WHERE EXISTS anstelle einer Verknüpfung umschreiben. Dies ist viel, viel schneller, da das Existieren nur eine einzelne Schlüsselsuche für jeden Datensatz in der linken Tabelle durchführen muss und keine Daten zurückgibt.

195voto

Andrew Lewis Punkte 4796
Table1                Table2
_______               _________
1                      2
2                      2
3                      5
4                      6

SELECT Table1.Id, 
       Table2.Id 
FROM Table1 
LEFT OUTER JOIN Table2 ON Table1.Id=Table2.Id

Ergebnisse:

1,null
2,2
2,2
3,null
4,null

62voto

HLGEM Punkte 91543

Das ist nicht unmöglich. Die Anzahl der Datensätze in der linken Tabelle ist die Mindestanzahl der Datensätze, die zurückgegeben werden. Wenn die rechte Tabelle zwei Datensätze enthält, die mit einem Datensatz in der linken Tabelle übereinstimmen, werden zwei Datensätze zurückgegeben.

0 Stimmen

Der alternative Fall wird für RIGHT JOIN oder FULL JOIN? passieren.

21voto

Um auf Ihr Postskriptum zu antworten: Das hängt davon ab, was Sie wollen.

Sie erhalten (möglicherweise) mehrere Zeilen für jede Zeile in Ihrer linken Tabelle, weil es mehrere Übereinstimmungen für die Verknüpfungsbedingung gibt. Wenn Sie möchten, dass Ihre Gesamtergebnisse die gleiche Anzahl von Zeilen enthalten wie der linke Teil der Abfrage, müssen Sie sicherstellen, dass Ihre Verknüpfungsbedingungen eine 1-zu-1-Übereinstimmung verursachen.

Alternativ können Sie, je nachdem, was Sie tatsächlich wollen, Aggregatfunktionen verwenden (wenn Sie beispielsweise nur eine Zeichenfolge aus dem rechten Teil benötigen, könnten Sie eine Spalte erzeugen, die eine durch Komma getrennte Zeichenfolge der Ergebnisse der rechten Seite für die linke Zeile ist).

Wenn Sie nur 1 oder 2 Spalten aus der äußeren Verknüpfung betrachten, können Sie eine skalare Unterabfrage verwenden, da Sie garantiert 1 Ergebnis erhalten.

7 Stimmen

Dies ist eine gute Antwort, da sie Vorschläge bietet, wie man nur Zeilen aus der linken Tabelle zurückgeben kann.

0 Stimmen

Alternatively, depending on what you actually want you can use aggregate functions (if for example you just want a string from the right part you could generate a column that is a comma delimited string of the right side results for that left row. Das ist genau das, was ich zu erreichen versuche, aber nicht herausgefunden habe, wie das geht.

15voto

Alex Martelli Punkte 805329

Jeder Datensatz aus der linken Tabelle wird so oft zurückgegeben, wie es übereinstimmende Datensätze in der rechten Tabelle gibt - mindestens 1, es können aber auch leicht mehr als 1 sein.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X