2012-03-08 12 views
125

Pomijając wyniki, czy otrzymam taki sam wynik z poniższych zapytań A i B? A co z C i D?Czy kolejność łączenia ma znaczenie w języku SQL?

-- A 
select * 
from a left join b 
      on <blahblah> 
     left join c 
      on <blahblan> 


-- B 
select * 
from a left join c 
      on <blahblah> 
     left join b 
      on <blahblan> 

-- C 
select * 
from a join b 
      on <blahblah> 
     join c 
      on <blahblan> 


-- D 
select * 
from a join c 
      on <blahblah> 
     join b 
      on <blahblan> 
+5

Co znajduje się w '' ? łączycie się z A do B i od A do C, czy przyłączacie się od A do B i od B do C? – beny23

+1

Cześć Beny, kod w moim pytaniu jest abstrakcją. Nie interesuje mnie dołączenie od A do B lub od A do C, chcę tylko wiedzieć, czy składnia taka zapewni identyczne wyniki. –

Odpowiedz

156

Dla INNER dołącza, nie, zamówienie nie ma znaczenia. Zapytania zwracają te same wyniki, o ile zmienisz swoje wybory z SELECT * na SELECT a.*, b.*, c.*.


Dla (LEFT, RIGHT lub FULL) OUTER łączy tak, sprawy zamówienie - i (aktualizowane) rzeczy są o wiele bardziej skomplikowane.

pierwsze zewnętrzne przyłącza nie są przemienne, tak a LEFT JOIN b nie jest taki sam jak b LEFT JOIN a

sprzężenia zewnętrzne nie są asocjacyjny albo, więc w swoich przykładach, które dotyczą zarówno (przemienność i skojarzenia) Właściwości:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id 
    LEFT JOIN c 
    ON c.ac_id = a.ac_id 

odpowiada:

a LEFT JOIN c 
    ON c.ac_id = a.ac_id 
    LEFT JOIN b 
    ON b.ab_id = a.ab_id 

a:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id 
    LEFT JOIN c 
    ON c.ac_id = a.ac_id 
    AND c.bc_id = b.bc_id 

nie odpowiada:

a LEFT JOIN c 
    ON c.ac_id = a.ac_id 
    LEFT JOIN b 
    ON b.ab_id = a.ab_id 
    AND b.bc_id = c.bc_id 

Innym (oby prostsze) Przykład Zespolenie. Potraktujcie to jako (a LEFT JOIN b) LEFT JOIN c:

a LEFT JOIN b 
    ON b.ab_id = a.ab_id   -- AB condition 
LEFT JOIN c 
    ON c.bc_id = b.bc_id   -- BC condition 

Ten jest równoznaczne do a LEFT JOIN (b LEFT JOIN c):

a LEFT JOIN 
    b LEFT JOIN c 
     ON c.bc_id = b.bc_id   -- BC condition 
    ON b.ab_id = a.ab_id   -- AB condition 

tylko dlatego, że mamy "Nice" ON warunki. Zarówno ON b.ab_id = a.ab_id, jak i c.bc_id = b.bc_id są kontrolami równości i nie obejmują porównań NULL.

Można nawet mieć warunki z innymi operatorami lub bardziej skomplikowanych, takich jak: ON a.x <= b.x lub ON a.x = 7 lub ON a.x LIKE b.x lub ON (a.x, a.y) = (b.x, b.y) i dwie kwerendy nadal byłyby równoważne.

Jeśli jednak każdy z tych zaangażowanych IS NULL lub funkcji, która jest związana z null jak COALESCE(), na przykład wtedy, gdy warunek był b.ab_id IS NULL, następnie dwa pytania nie byłyby równoważne.

+2

To jest bardziej poprawne, aby powiedzieć, że sprzężenie zewnętrzne jest asocjatywne, o ile żaden predykat nie może być spełniony przez wiersz, w którym wszystkie kolumny z jednej tabeli mają wartość NULL, niż stwierdzenie, że jest to asocjacja, o ile predykaty nie obejmują wartości IS NULL lub "funkcja związana z zerami". Można łatwo wyobrazić sobie predykat, który spełnia poprzedni opis, ale nie ten ostatni, jak "a. Sececol" 0 OR b.someothercol> 0'; Zespolenie może zakończyć się niepowodzeniem w przypadku tego warunku. –

+0

Ale tak, myślę, że technicznie słuszne jest stwierdzenie, że OUTER JOIN jest asocjatywny, o ile predykat nie spełnia żadnego z warunków, które tu opisuję: http://stackoverflow.com/questions/20022196/are-left- outer-join-asocjacyjny/20022925 # 20022925 (pierwszy z nich również zrywa powiązania dla INNER JOINs, ale jest to tani i oczywisty sposób na przełamanie go, że być może nie jest to warte wspomnienia.) Warto również podkreślić, że najbardziej wspólny rodzaj DOŁĄCZENIA - ŁĄCZENIE z kluczem obcym - nie spełnia żadnego z tych warunków, a zatem jest miły i towarzyski. –

+0

@MarkAmery Dziękuję, ciężko mi było sformułować moje zdania na ten temat (i już przegłosowałem tę twoją odpowiedź;) –

4

dla zwykłych połączeń, nie ma. TableA join TableB wykona ten sam plan wykonania co TableB join TableA (aby twoje przykłady C i D były takie same)

dla lewych i prawych połączeń.TableA left Join TableB jest inna niż TableB left Join TableA, ale jej to samo niż TableB right Join TableA

+2

Dotyczy to tylko komutatywności, ale przykłady w pytaniu pokazują, że pytający jest zainteresowany asocjatywnością. Odpowiedź ypercube odnosi się do obu. –

Powiązane problemy