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?

10voto

A-K Punkte 16460

Wenn Sie nur eine beliebige Zeile auf der rechten Seite benötigen

SELECT SuspReason, SiteID FROM(
    SELECT SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID, ROW_NUMBER()
    OVER(PARTITION BY SUSP.Susp_Visits.SiteID) AS rn
    FROM SUSP.Susp_Visits
    LEFT OUTER JOIN DATA.Dim_Member ON SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum
) AS t
WHERE rn=1

oder einfach

SELECT SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID
FROM SUSP.Susp_Visits WHERE EXISTS(
    SELECT DATA.Dim_Member WHERE SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum
)

1 Stimmen

Da Sie keine DDL und DML zur Verfügung gestellt haben, habe ich keinen Test durchgeführt. Auf jeden Fall denke ich, dass EXISTS das ist, was Sie wollen. Versuchen Sie dies: SELECT SuspReason, SiteID FROM( SELECT SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID, ROW_NUMBER() OVER(PARTITION BY SUSP.Susp_Visits. SiteID ORDER BY SUSP.Susp_Visits.SiteID) AS rn FROM SUSP.Susp_Visits LEFT OUTER JOIN DATA.Dim_Member ON SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum ) AS t WHERE rn=1

9voto

Ken Burkhardt Punkte 3508

Könnte es sich um eine Eins-zu-viele-Beziehung zwischen der linken und der rechten Tabelle handeln?

8voto

topchef Punkte 17965

LEFT OUTER JOIN gibt genau wie INNER JOIN (normale Verknüpfung) für jede Zeile in der linken Tabelle so viele Ergebnisse zurück, wie es Übereinstimmungen in der rechten Tabelle gibt. Daher können Sie viele Ergebnisse erhalten - bis zu N x M, wobei N die Anzahl der Zeilen in der linken Tabelle und M die Anzahl der Zeilen in der rechten Tabelle ist.

Die Mindestanzahl der Ergebnisse ist bei LEFT OUTER JOIN immer garantiert mindestens N.

1 Stimmen

Ich begann zu überlegen, wann die Anzahl der Zeilen gleich N x M ist, und die einzige echte Situation, die mir in den Sinn kommt, ist, wenn N oder M gleich 1 ist. Sind Sie einverstanden?

2 Stimmen

Nein, ich weiß es nicht. Sie sollten die Join-Bedingung nicht nur als Key Equality Join betrachten. Es kann eine beliebige Bedingung sein, z. B. Datumsbereiche, Ungleichungen usw. Zwei Extremfälle: (a) N Zeilen haben keine einzige Übereinstimmung unter M Zeilen, dann führt der Left Outer Join zu N Zeilen, die mit NULLs übereinstimmen. (b) jede der N Zeilen stimmt mit allen M Zeilen überein, dann ist das Ergebnis ein N x M Zeilen Set.

1 Stimmen

Sie haben Recht, ich habe die Verbindungen nur im Hinblick auf die Gleichheit der Schlüssel betrachtet. Ihr Beispiel aus "Fall b" gefällt mir. Ich glaube, dass "jede von N Zeilen mit allen von M Zeilen übereinstimmt" ein allgemeines Rezept für den Fall ist, dass N x M Zeilen zurückgegeben werden, was ziemlich unmöglich zu visualisieren ist, wenn man nur an die Gleichheit der Schlüssel denkt.

5voto

Serge Punkte 59

Achten Sie darauf, wenn Sie eine Where-Klausel auf der "rechten Seite" der Tabelle einer Abfrage haben, die einen Left Outer Join enthält... Wenn Sie keinen Datensatz auf der rechten Seite haben, der die Where-Klausel erfüllt, dann wird der entsprechende Datensatz der Tabelle auf der "linken Seite" nicht im Ergebnis Ihrer Abfrage erscheinen....

1 Stimmen

Fügen Sie dann die Bedingung in die ON-Klausel des entsprechenden LEFT OUTER JOIN ein.

0 Stimmen

El WHERE Klausel ist nicht Teil der "rechten" oder "linken" Seite der SELECT Anweisung gehört sie zur Menge aller Joins und gilt daher für das Ergebnis aller Joins (d. h., nach Beitritt, nicht während verbinden). Wie @Mik sagt, sollten solche Bedingungen, die nur für die "linke" oder "rechte" Seite gelten, Teil der ON Klausel einer JOIN Erklärung.

2voto

bdukes Punkte 144019

Es scheint, als gäbe es mehrere Zeilen in der Tabelle DATA.Dim_Member pro Zeile SUSP.Susp_Visits.

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