Mam bardzo podstawowe LEFT OUTER JOIN, aby zwrócić wszystkie wyniki z lewej tabeli i kilka dodatkowych informacji ze znacznie większej tabeli. Lewa tabela zawiera 4935 rekordów, ale kiedy opuściłem OUTER JOIN do dodatkowej tabeli, liczba rekordów jest znacznie większa.
O ile wiem, jest absolutną ewangelią, że LEFT OUTER JOIN zwróci wszystkie rekordy z lewej tabeli z dopasowanymi rekordami z prawej tabeli i wartościami zerowymi dla wszystkich wierszy, których nie można dopasować, jako takie rozumiem, że powinno zwrócenie większej liczby wierszy niż istnieje w tabeli po lewej stronie jest niemożliwe, ale to się dzieje tak samo!
Zapytanie SQL następuje:
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
Być może popełniłem błąd w składni lub moje rozumienie LEFT OUTER JOIN jest niekompletne, mam nadzieję, że ktoś może wyjaśnić, jak to się dzieje?
Postscriptum
Dzięki za świetne odpowiedzi, moje rozumienie LEFT OUTER JOINS jest teraz znacznie lepsze. Czy ktokolwiek mógłby jednak zasugerować sposób zmodyfikowania tego zapytania, aby uzyskać tylko tyle zwróconych rekordów, ile istnieje w lewej tabeli?
To zapytanie służy wyłącznie do wygenerowania raportu, a zduplikowane dopasowania po prostu komplikują sprawę.
/Postscriptum
źródło
Odpowiedzi:
LEFT OUTER JOIN zwróci wszystkie rekordy z tabeli LEFT połączone z tabelą RIGHT, jeśli to możliwe.
Jeśli jednak istnieją dopasowania, nadal zwróci wszystkie pasujące wiersze, dlatego jeden wiersz w LEWEJ, który pasuje do dwóch wierszy w PRAWO, zwróci jako dwa WIERSZE, tak jak INNER JOIN.
EDYCJA: W odpowiedzi na Twoją zmianę właśnie przyjrzałem się Twojemu zapytaniu i wygląda na to, że zwracasz tylko dane z LEWEJ tabeli. Dlatego, jeśli chcesz tylko danych z tabeli LEFT i chcesz, aby zwracany był tylko jeden wiersz dla każdego wiersza w tabeli LEFT, nie musisz w ogóle wykonywać JOIN i możesz po prostu wykonać polecenie SELECT bezpośrednio z tabeli LEFT.
źródło
Wyniki:
źródło
To nie jest niemożliwe. Liczba rekordów w lewej tabeli to minimalna liczba rekordów, które zwróci. Jeśli w prawej tabeli są dwa rekordy, które pasują do jednego rekordu w lewej tabeli, zwróci dwa rekordy.
źródło
W odpowiedzi na Twój postscript, to zależy od tego, co chcesz.
Otrzymujesz (możliwe) wiele wierszy dla każdego wiersza w lewej tabeli, ponieważ istnieje wiele dopasowań dla warunku sprzężenia. Jeśli chcesz, aby wszystkie wyniki miały taką samą liczbę wierszy, jak w lewej części zapytania, upewnij się, że warunki łączenia powodują dopasowanie 1 do 1.
Alternatywnie, w zależności od tego, czego naprawdę chcesz, możesz użyć funkcji agregujących (jeśli na przykład chcesz tylko ciąg z prawej części, możesz wygenerować kolumnę, która jest ciągiem rozdzielanym przecinkami z prawej strony wyników dla tego lewego wiersza.
Jeśli patrzysz tylko na 1 lub 2 kolumny ze sprzężenia zewnętrznego, możesz rozważyć użycie podzapytania skalarnego, ponieważ będziesz mieć zagwarantowany 1 wynik.
źródło
Każdy rekord z lewej tabeli zostanie zwrócony tyle razy, ile pasujących rekordów znajduje się w prawej tabeli - co najmniej 1, ale z łatwością może być ich więcej niż 1.
źródło
LEFT OUTER JOIN podobnie jak INNER JOIN (zwykłe sprzężenie) zwróci tyle wyników dla każdego wiersza w lewej tabeli, ile dopasowań znajdzie w prawej tabeli. Stąd możesz mieć wiele wyników - aż do N x M, gdzie N to liczba wierszy w lewej tabeli, a M to liczba wierszy w prawej tabeli.
Minimalna liczba wyników jest zawsze gwarantowana w LEFT OUTER JOIN na co najmniej N.
źródło
Czy może to być relacja jeden do wielu między lewym i prawym stołem?
źródło
Zwróć uwagę, jeśli masz klauzulę where w tabeli "prawej strony" zapytania zawierającej lewe sprzężenie zewnętrzne ... W przypadku, gdy nie masz rekordu po prawej stronie spełniającego klauzulę where, wtedy odpowiadający rekord "lewej strony" 'tabela nie pojawi się w wyniku zapytania ....
źródło
Jeśli potrzebujesz tylko jednego rzędu z prawej strony
Lub tylko
źródło
Wygląda na to, że w tabeli DATA.Dim_Member znajduje się wiele wierszy na wiersz SUSP.Susp_Visits.
źródło
jeśli wiele (x) wierszy w Dim_Member jest powiązanych z jednym wierszem w Susp_Visits, w zestawie wyników będzie x wierszy.
źródło