Powód, dla którego wolisz PRAWE DOŁĄCZENIE niż LEWE DOŁĄCZENIE


18

Jeśli dobrze rozumiem, co RIGHT JOIN:

SELECT Persons.*, Orders.*
FROM Orders
RIGHT JOIN Persons ON Orders.PersonID = Persons.ID

można wyrazić jako LEFT JOIN:

SELECT Persons.*, Orders.*
FROM Persons
LEFT JOIN Orders ON Persons.ID = Orders.PersonID

Moja osobista opinia jest taka, że ​​intencja tego oświadczenia:

  • Najpierw zdobądź Persons
  • Następnie rozwiń / powtórz w Personsrazie potrzeby, aby dopasowaćOrders

jest lepiej wyrażony przez kolejność Persons LEFT JOIN Ordersniż przez odwrotną kolejność Orders RIGHT JOIN Persons(i nigdy nie używam RIGHT JOINw rezultacie).

Czy są jakieś sytuacje, w których RIGHT JOINpreferowany jest a ? Lub czy są jakieś przypadki użycia, w których RIGHT JOINmożna zrobić coś, LEFT JOINczego nie można?


12
Nie mogę sobie przypomnieć jednego przypadku, w którym chciałem dobrze dołączyć. Miałem przypadki, w których plan wykonania zapytania zamienił lewe złączenie w prawe złączenie ze względu na wydajność. Ale z czystego punktu widzenia pisania kodu, nie, nie przypominam sobie, aby kiedykolwiek pisałem właściwe połączenie.
Brandon

2
Nie uważam tego za pytanie dotyczące „wyjaśniania, pisania lub debugowania kodu”. Pytanie dotyczy tego, dlaczego język ma dwie cechy, które najwyraźniej robią to samo, jeśli w rzeczywistości istnieje między nimi jakaś różnica, a jeśli nie, kiedy preferowana byłaby „nieoczywista”.
Philip Kendall

1
Nie, lewe łączenie prawie zawsze ujmuje to, czego potrzebujesz najbardziej zwięźle i jest łatwiejsze do uzasadnienia. W moim miejscu pracy mamy standard zapobiegający prawemu łączeniu, ponieważ nigdy nie ma potrzeby, aby były one konieczne (tj. Zawsze można je zastąpić łączeniem po przeciwnej lewej stronie).
mgw854

8
Zresetowałem głosowanie końcowe - to pytanie jest tutaj na temat, ponieważ zrozumienie różnicy między łączeniami wpływa na projektowanie oprogramowania (projektowanie baz danych jest częścią projektowania oprogramowania, podobnie jak algorytmy, które mogą sprawdzać bazy danych). Może to być również temat na temat Administratorów baz danych , a także może być tam duplikat.
Thomas Owens

1
Nie jestem pewien, czy sugerujesz, że RIGHT JOINjest to zalecane lub bardziej powszechne. Jeśli to twoja przesłanka, jest niepoprawna. Nie mogę sobie wyobrazić czasu, w którym kiedykolwiek widziałem właściwe sprzężenie użyte w kodzie ani w przykładach. To jest JOINlub LEFT OUTER JOIN. W rzadkich przypadkach możesz zobaczyć FULL OUTER JOIN.
JimmyJames

Odpowiedzi:


12

To zależy od tego, jaki wymóg starasz się spełnić.

To nie to samo, co powiedzieć: „daj wszystkim osobom i odpowiadającym im rozkazom”, że „Chcę wszystkich rozkazów z ich odpowiednimi osobami” , szczególnie jeśli zamierzasz is nullprzynieść wiersze bez odpowiadającego im dopasowania. To właśnie nazywam „dominującą tabelą”, czyli tabelą, z której chcę pobierać wiersze, niezależnie od tego, że po drugiej stronie złączenia nie ma odpowiedniego wiersza.

Spójrz na te obrazy, a zauważysz, że nie są takie same:

wprowadź opis zdjęcia tutaj

Źródłem obrazu jest ten znakomity artykuł .

Ale masz rację, że oba wymagania można spełnić, łącząc albo odwracając kolejność tabel w złączeniu.

Sądzę jednak, że dla zachodnich ludzi przyzwyczajonych do pisania od lewej do prawej bardziej naturalnie jest stosować lewe łączenia nad prawymi złączeniami , ponieważ widzimy, że chcemy, aby sprzężenia były w tym samym kierunku lub w tej samej kolejności co selectkolumny ed.

Możliwym powodem preferowania właściwego łączenia jest to, że w twojej kulturze piszesz od prawej do lewej (jak w arabskim lub hebrajskim systemie pisania) i zwykle myślisz w ten sposób, co oznacza, że ​​być może w twoim mózgu informacje tekstowe przepływają od prawej do lewej .

Niektórzy lingwiści uważają, że Twój język wpływa na twój sposób myślenia: https://www.edge.org/conversation/lera_boroditsky-how-does-our-language-shape-the-way-we-think


1
Zacząłem myśleć w ten sposób, ale nie sądzę, aby było to poprawne. Zacząłem wyobrażać sobie pisanie SQL po hebrajsku (czego nigdy tak naprawdę nie zrobiłem). OK: wyrównanie do prawej, od prawej do lewej, z góry na dół. Nadal będziesz wymieniał tabelę A najpierw, a następnie tabelę B. Przy właściwym łączeniu wykluczysz (szczególnie w przypadku zerowym) większość lub całość tabeli wymienionej jako pierwsza. Myślę, że ludzki umysł zwykle kojarzy się najpierw z pierwotnym i najważniejszym . Dzieje się tak niezależnie od kierunku pisania. Możesz nazwać je „FIRST JOIN” i „SECOND JOIN”, a to uprzedzenie nadal występowałoby.
Mike wspiera Monikę

Podaję link do obrazka, który pokazałeś poniżej.
Jon Raynor,

@Mike Nie sugeruję, aby ludzie pisali SQL w języku arabskim lub hebrajskim. Po prostu orientacja języka ojczystego może być powodem, dla którego wolisz odpowiednie połączenia. Ale to tylko możliwość. Uważam, że lewe połączenia są bardziej naturalne.
Tulains Córdova

Teraz należycie podziękowałem twórcy obrazu. Mam go od lat w HD i nie pamiętam, skąd pochodzi
Tulains Córdova

Mówię płynnie po hebrajsku i nadal uważam, że jest LEFT JOINbardziej naturalny.
Zev Spitz,

3

Nie ma nic (o czym wiem), co można zrobić z prawym złączeniem, czego nie można zrobić z lewym złączeniem. Ale czasami składnia z lewymi złączeniami jest brzydsza. Powiedzmy, że masz następujące tabele:

Persons
ID | Name

Orders
ID | CustomerId | other unimportant stuff

SpecialOrderDetails
ID | OrderId | other stuff

Powiedzmy, że musisz uzyskać listę wszystkich osób w bazie danych i wszystkich ich zamówień ze specjalnymi szczegółami zamówienia (powiemy, że nie wszystkie zamówienia mają specjalne szczegóły zamówienia). Więc zwykle wykonujesz lewe łączenie od ludzi do zamówień. Ale musisz dołączyć w szczegółach specjalnych zamówień. Jeśli użyjesz tam połączenia wewnętrznego, to skutecznie sprawi, że lewe połączenie od ludzi zamieni się w połączenie wewnętrzne. IE: to jest to, co chcesz zrobić, ale nie działa (wykluczy to każdego, kto nie ma specjalnego zamówienia):

select p.*, o.*, d.*
from Persons p
left join Orders o on o.CustomerId = p.Id
inner join SpecialOrderDetails d on d.OrderId = o.Id

Więc możesz przepisać to tak:

--get all the people without a special order
select p.*, NULL, NULL, ... --NULLs placeholders for all the fields from OrderDetails and SpecialOrderDetails
from Persons p
left join Orders o on o.CustomerId = p.Id
left join SpecialOrderDetails d on d.OrderId = o.Id
where o.Id is null 

union

--get all the people with a special order
select p.*, o.*, d.*
from Persons p
inner join Orders o on o.CustomerId = p.Id
inner join SpecialOrderDetails d on d.OrderId = o.Id

Nie do końca jasne (zakładając brak komentarzy), ale spełnia swoje zadanie. Jeśli jest to coś więcej niż jednorazowe (tj. Coś, co kiedyś będzie musiało wrócić i utrzymywać), użycie odpowiedniego łączenia może wyjaśnić, co było celem.

select p.*, o.*, d.*
from Orders o
inner join SpecialOrderDetails d on d.OrderId = o.Id
right join Persons p on p.Id = o.CustomerId

Co jest nieco bardziej zwięzłe i jasne (ale tylko jeśli ktokolwiek to czyta, rozumie właściwe dołączenia). Zauważ, że można to napisać przy lewych złączeniach, ale wymaga to zagnieżdżenia (z którym prawdopodobnie mniej osób jest zaznajomionych niż prawe).

select p.*, o.*, d.*
from Persons p
left join Orders o 
    inner join SpecialOrderDetails d on d.OrderId = o.Id
on o.CustomerId = p.Id

W tym momencie jest to wybór tego, co jest najbardziej zrozumiałe i co zrozumie większość ludzi (czy wiesz, jak korzystać z tej składni, jeśli nie wiesz, że nazywa się to łączeniem zagnieżdżonym?).

Krótko mówiąc, nie potrzebujesz dokładnie odpowiednich połączeń, ale mogą one ułatwić czytanie.


Myślę, że może jesteś po prostu praworęczny.
Robert Harvey

Nie rozumiem, dlaczego nie można napisać wielokrotne lewej dołącza w tym przypadku: SELECT p.*, o.*, d.* FROM Persons p LEFT JOIN Orders o ON o.CustomerID = p.ID LEFT JOIN SpecialOrders d ON o.Id = d.OrderID.
Zev Spitz,

@RobertHarvey Jestem, ale nie jestem pewien, co ma z tym wspólnego przekaz.
Becuzz

@ZevSpitz Być może nie było jasne z tego, co napisałem, ale pomysł polegał na tym, że chciałeś tylko pól z zamówień tylko wtedy, gdy istnieje specjalny rekord szczegółów zamówienia, tj. pozostało dołącz do nich tylko wtedy, gdy istnieje ich para.
Becuzz

-1

Widziałem PRAWE DOŁĄCZENIE używane do celów replikacji / scalania. Powiedzmy, że mam dwie tabele A i B. A jest po lewej stronie, a B po prawej. Powiedzmy, że chciałem zreplikować dane między tymi dwiema tabelami, aby były równoważne.

Gdybym chciał pokazać wszystkie dane, które były w A, ale nie w B, byłoby to połączenie LEWE. Gdybym chciał pokazać wszystkie dane w B, które nie były w A, PRAWO dołączyłbym.

Czasami LEWO i PRAWO przydają się przy scalaniu i replikacji danych, aby zachować perspektywę.

Poza tym nie widzę żadnego innego powodu, aby używać PRAWEGO połączenia, ponieważ wszystkie PRAWE sprzężenia można przekształcić w PRAWE sprzężenia lub odwrotnie, wszystkie PRAWE sprzężenia można przekonwertować na PRAWE sprzężenia w zależności od tego, w jaki sposób tabele są uporządkowane lub wizualizowane. Byłoby to więc kwestia preferencji w innych przypadkach.

Oto ładny link do wizualizacji połączeń SQL.

http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins


-1

lewe złączenie nie jest przeciwieństwem złączenia prawego, sprawdź następujący przypadek, który daje różne wyniki

select * from 
(select 1 as x  where 1=1) a left join 
(select 1 as x  where 1=0) b on a.x=b.x inner join 
(select 1 as x  where 1=1) c on b.x=c.x

select * from 
(select 1 as x where 1=1) c inner join 
(select 1 as x where 1=0) b on c.x=b.x right join 
(select 1 as x where 1=1) a on b.x=a.x

tabele b anc c są zawsze połączone wewnętrznie, ale w pierwszym a jest pozostawione połączone z innymi, a w drugim a jest połączone prawym

lewy łączenie nie zwraca wierszy, a prawy łączenie zwraca wiersz


brzmi to bardziej jako komentarz styczny, zobacz Jak odpowiedzieć
gnat

-2

Nigdy nie ma powodu, aby preferować RIGHT JOINi LEFT JOINjest o wiele jaśniejsze:

WYBIERZ Osoby. *, Zamówienia. * OD OSÓB LEWE DOŁĄCZ Zamówienia ON Persons.ID = Orders.PersonID

ponieważ pozwala natychmiast zobaczyć, która tabela jest sprawdzana. Natomiast z RIGHT JOIN:

WYBIERZ Osoby. *, Zamówienia. * Z ZAMÓWIEŃ DOŁĄCZ PRAWO Osoby NA Orders.PersonID = Persons.ID

pierwsza tabela jest zapisana po JOIN.

Z mojego doświadczenia nigdy nie widziałem RIGHT JOIN.


1
Co to dodaje do pytania? Pytanie nie brzmi, jaka jest różnica? ; Pytanie brzmi: dlaczego powinienem użyć RIGHT JOIN? .
Zev Spitz,

@ZevSpitz Pytasz o powód, dla którego preferujesz który, podaję powód. Który przypadek użycia nie ma znaczenia, ponieważ jest to kwestia gustu.
kirie
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.