Lewe i prawe złączenia @avi są podobne, jeśli nie przejmujesz się, na której podstawowej tabeli opiera się łączenie.
Anup
2
@philipxy: To dziwna definicja (nawet jeśli masz rację). Ale wolę przejść na drugą stronę i zacząć od łączenia krzyżowego, a następnie „zbudować” połączenie wewnętrzne na nim. W końcu sama koncepcja łączenia krzyżowego unieważnia te nieformalne i niedokładne wizualizacje diagramu Venna ...
Lukas Eder
1
Te zdjęcia zdają się sugerować, że połączenie jest takie samo jak pełne połączenie zewnętrzne, a przecięcie jest takie samo jak połączenie wewnętrzne, co nie jest prawidłowe, o ile mi wiadomo.
mightyWOZ
1
@DevDave, ponieważ wbrew powszechnemu przekonaniu - obraz nie jest wart tysiąca słów. Zobacz następną odpowiedź.
hyankov,
248
Co to jest SQL JOIN?
SQL JOIN to metoda pobierania danych z dwóch lub więcej tabel baz danych.
W tego rodzaju a JOINotrzymujemy wszystkie rekordy, które pasują do warunków w obu tabelach, a rekordy w obu tabelach, które nie pasują, nie są raportowane.
Innymi słowy, INNER JOINopiera się na jednym fakcie, że: TYLKO pasujące pozycje ZARÓWNO MUSZĄ zostać wymienione tabele.
Zauważ, że JOINbez żadnych innych JOINsłów kluczowych (takich jak INNER, OUTER, LEFTitp) jest INNER JOIN. Innymi słowy, JOINjest cukrem syntaktycznym dla INNER JOIN(patrz: Różnica między JOIN a INNER JOIN ).
2. DOŁĄCZ DO ZEWNĘTRZNEJ:
OUTER JOIN pobiera
Albo dopasowane wiersze z jednej tabeli i wszystkie wiersze w drugiej tabeli Lub wszystkie wiersze we wszystkich tabelach (nie ma znaczenia, czy istnieje dopasowanie).
Istnieją trzy rodzaje łączenia zewnętrznego:
2.1 LEWE DOŁĄCZENIE ZEWNĘTRZNE lub LEWE DOŁĄCZENIE
To połączenie zwraca wszystkie wiersze z lewej tabeli w połączeniu z pasującymi wierszami z prawej tabeli. Jeśli w prawej tabeli nie ma pasujących kolumn, zwracane są NULLwartości.
2.2 PRAWE DOŁĄCZENIE DO ZEWNĄTRZ lub PRAWE DOŁĄCZENIE
Te JOINwszystkie powroty wiersze z prawej tabeli w połączeniu z wierszami pasujące Od lewej tabeli. Jeśli w lewej tabeli nie ma pasujących kolumn, zwracane są NULLwartości.
2.3 PEŁNE DOŁĄCZENIE ZEWNĘTRZNE lub PEŁNE DOŁĄCZENIE
Te JOINkombajny LEFT OUTER JOINi RIGHT OUTER JOIN. Zwraca wiersze z dowolnej tabeli, gdy warunki są spełnione, i zwraca NULLwartość, gdy nie ma zgodności.
Innymi słowy, OUTER JOINopiera się na fakcie, że: POWINIEN być wymienione TYLKO pasujące wpisy w JEDNEJ tabeli (PRAWO lub LEWO) lub OBIE tabele (PEŁNE).
Note that `OUTERJOIN`is a loosened form of`INNERJOIN`.
3. NATURALNE DOŁĄCZENIE:
Opiera się na dwóch warunkach:
JOINjest wykonana na wszystkich kolumn o tej samej nazwie na rzecz równości.
Usuwa zduplikowane kolumny z wyniku.
Wydaje się to mieć charakter bardziej teoretyczny, w wyniku czego (prawdopodobnie) większość DBMS nawet nie zadaje sobie trudu poparcia tego.
4. POŁĄCZENIE KRZYŻOWE:
Jest to iloczyn kartezjański dwóch zaangażowanych tabel. Wynik CROSS JOINnie ma sensu w większości sytuacji. Co więcej, nie będziemy tego wcale potrzebować (a przynajmniej potrzebują, by być precyzyjnym).
5. DOŁĄCZ DO:
Nie jest to inna forma JOIN, raczej jest to JOIN( INNER, OUTERitp) od stołu do siebie.
DOŁĄCZENIA oparte na operatorach
W zależności od operatora użytego w JOINklauzuli mogą istnieć dwa typy JOINs. Oni są
Equi DOŁĄCZ
Theta DOŁĄCZ
1. Equi DOŁĄCZ:
Dla dowolnego JOINtypu ( INNER, OUTERitp.), Jeśli użyjemy TYLKO operatora równości (=), wtedy powiemy, że JOINjest to EQUI JOIN.
2. Theta DOŁĄCZ:
Jest to to samo, EQUI JOINale pozwala wszystkim innym operatorom, takim jak>, <,> = itd.
Wielu uważa, zarówno EQUI JOINi Theta JOINpodobna do INNER, OUTER
etc JOINs. Ale głęboko wierzę, że jest to błąd i sprawia, że pomysły są niejasne. Ponieważ INNER JOIN, OUTER JOINwszyscy etc są połączone z tabelami i ich danych, natomiast EQUI JOINi THETA JOINsą połączone tylko z operatorami, których używamy w tej pierwszej.
Znów jest wielu, którzy uważają NATURAL JOINza swego rodzaju „osobliwy” EQUI JOIN. W rzeczywistości jest to prawdą z powodu pierwszego warunku, o którym wspomniałem NATURAL JOIN. Nie musimy jednak ograniczać się do tego NATURAL JOINsamego. INNER JOINs, OUTER JOINs itp. też może być EQUI JOIN.
Chociaż wydaje się to rozsądne, nie sądzę, aby odpowiadało „czym jest sprzężenie SQL” w jakikolwiek sposób, który przekazuje przydatne informacje. Odpowiedź jako całość to odniesienie napisane dla osób, które już rozumieją przyłączenia, a nie dla osób, które zadają te pytania. Pomija również odniesienia, zarówno w celu uzasadnienia swoich roszczeń (co jest właściwe, jeśli udziela się autorytatywnej odpowiedzi), jak i w celu zapewnienia dodatkowych wyjaśnień za pośrednictwem zasobów zewnętrznych. Jeśli próbujesz napisać autorytatywną odpowiedź, aby połączyć nowych użytkowników SQL, warto nieco wypełnić puste pola, zwłaszcza część „co to jest łączenie”.
Craig Ringer
czy możesz podać jakieś przykłady?
avi
67
Definicja:
ŁĄCZENIA są sposobem na zapytanie danych połączonych jednocześnie z wielu tabel jednocześnie.
Rodzaje ŁĄCZNIKÓW:
W przypadku RDBMS istnieje 5 rodzajów sprzężeń:
Equi-Join: Łączy wspólne rekordy z dwóch tabel w oparciu o warunek równości. Technicznie rzecz biorąc, łączenie wykonane za pomocą operatora równości (=) w celu porównania wartości klucza podstawowego jednej tabeli i wartości klucza obcego innej tabeli, dlatego zestaw wyników zawiera wspólne (dopasowane) rekordy z obu tabel. Wdrożenie patrz INNER-JOIN.
Natural-Join: Jest to ulepszona wersja Equi-Join, w której operacja SELECT pomija duplikat kolumny. Wdrożenie patrz INNER-JOIN
Non-Equi-Join: Jest odwrotnością Equi-join, gdzie warunkiem łączenia jest użycie operatora innego niż równy (=) np.! =, <=,> =,>, <Lub MIĘDZY itp. W celu uzyskania informacji na temat implementacji patrz WEWNĘTRZNE ŁĄCZENIE.
Self-Join:: Dostosowane zachowanie złączenia, w którym stół łączy się ze sobą; Jest to zwykle potrzebne do tworzenia zapytań w tabelach z odnośnikami (lub jednostkową jednostką relacji). Aby zapoznać się z implementacją, zobacz WEWNĘTRZNE ŁĄCZENIA.
Produkt kartezjański: krzyż łączy wszystkie rekordy obu tabel bez żadnych warunków. Technicznie zwraca zestaw wyników zapytania bez klauzuli WHERE.
Zgodnie z troską i postępem SQL istnieją 3 typy sprzężeń, a wszystkie sprzężenia RDBMS można uzyskać za pomocą tych rodzajów sprzężeń.
INNER-JOIN: Łączy (lub łączy) dopasowane wiersze z dwóch tabel. Dopasowywanie odbywa się na podstawie wspólnych kolumn tabel i ich operacji porównywania. Jeżeli warunek oparty jest na równości, wówczas: Wykonano EQUI-JOIN, w innym przypadku Non-EQUI-Join.
OUTER-JOIN: Łączy (lub łączy) dopasowane wiersze z dwóch tabel i niepasujące wiersze z wartościami NULL. Można jednak dostosować wybór niepasujących wierszy, np. Wybierając niepasujący wiersz z pierwszej tabeli lub drugiej tabeli według podtypów: POŁĄCZENIE ZEWNĘTRZNE i POŁĄCZENIE ZEWNĘTRZNE.
2.1 LEFT Outer JOIN (aka, LEFT-JOIN): Zwraca tylko dopasowane wiersze z dwóch tabel i niepasujące tylko z tabeli LEFT (tj. Pierwszej tabeli).
2.2 RIGHT Outer JOIN (aka, RIGHT-JOIN): Zwraca dopasowane wiersze z dwóch tabel i niepasujące tylko z prawej tabeli.
2.3 FULL OUTER JOIN (alias OUTER JOIN): Zwraca dopasowane i niepasujące z obu tabel.
CROSS-JOIN: To połączenie nie łączy się / nie łączy, lecz tworzy produkt kartezjański.
Uwaga: Self-JOIN można osiągnąć za pomocą INNER-JOIN, OUTER-JOIN i CROSS-JOIN na podstawie wymagań, ale tabela musi łączyć się ze sobą.
Etykiety „Tabela 1” i „Tabela 2” oraz etykiety poniżej są nieodpowiednie, pochodzą z ilustracji intersect/ except/ union; tutaj koła są wierszami zwracanymi przez left& rightjoin, jak mówią ponumerowane etykiety. Obraz AXB jest nonsensem. cross join= inner join on 1=1& jest specjalnym przypadkiem pierwszego diagramu.
philipxy
Warto wspomnieć, że SQL-92 definiuje UNION JOIN. Teraz jest przestarzały w SQL: 2003.
The Impaler
40
Co ciekawe, większość innych odpowiedzi ma te dwa problemy:
Koncentrują się tylko na podstawowych formach łączenia
Przede wszystkim: DOŁĄCZY to produkty kartezjańskie
Dlatego diagramy Venna wyjaśniają je tak niedokładnie, ponieważ JOIN tworzy iloczyn kartezjański między dwoma połączonymi tabelami. Wikipedia ładnie to ilustruje:
Składnia SQL dla produktów kartezjańskich to CROSS JOIN. Na przykład:
SELECT*-- This just generates all the days in January 2017FROM generate_series('2017-01-01'::TIMESTAMP,'2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
INTERVAL '1 day')AS days(day)-- Here, we're combining all days with all departmentsCROSSJOIN departments
Który łączy wszystkie wiersze z jednej tabeli ze wszystkimi wierszami z drugiej tabeli:
Źródło:
+--------+ +------------+
| day | | department |
+--------+ +------------+
| Jan 01 | | Dept 1 |
| Jan 02 | | Dept 2 |
| ... | | Dept 3 |
| Jan 30 | +------------+
| Jan 31 |
+--------+
Wynik:
+--------+------------+
| day | department |
+--------+------------+
| Jan 01 | Dept 1 |
| Jan 01 | Dept 2 |
| Jan 01 | Dept 3 |
| Jan 02 | Dept 1 |
| Jan 02 | Dept 2 |
| Jan 02 | Dept 3 |
| ... | ... |
| Jan 31 | Dept 1 |
| Jan 31 | Dept 2 |
| Jan 31 | Dept 3 |
+--------+------------+
Jeśli po prostu napiszemy listę tabel oddzieloną przecinkami, otrzymamy to samo:
-- CROSS JOINing two tables:SELECT*FROM table1, table2
INNER JOIN (Theta-JOIN)
Jest INNER JOINto po prostu filtrowany, w CROSS JOINktórym predykat filtru jest wywoływany Thetaw algebrze relacyjnej.
Na przykład:
SELECT*-- Same as beforeFROM generate_series('2017-01-01'::TIMESTAMP,'2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
INTERVAL '1 day')AS days(day)-- Now, exclude all days/departments combinations for-- days before the department was createdJOIN departments AS d ON day >= d.created_at
Pamiętaj, że słowo kluczowe INNERjest opcjonalne (z wyjątkiem MS Access).
Specjalnym rodzajem Theta-JOIN jest equi JOIN, którego używamy najczęściej. Predykat łączy klucz podstawowy jednej tabeli z kluczem obcym innej tabeli. Jeśli użyjemy bazy danych Sakila do zilustrowania, możemy napisać:
SELECT*FROM actor AS a
JOIN film_actor AS fa ON a.actor_id = fa.actor_id
JOIN film AS f ON f.film_id = fa.film_id
Łączy to wszystkich aktorów z ich filmami.
Lub też w niektórych bazach danych:
SELECT*FROM actor
JOIN film_actor USING(actor_id)JOIN film USING(film_id)
USING()Składnia pozwala na określenie kolumny, które muszą być obecne na obu stronach łączenia tabel operacja i tworzy predykat równości w tych dwóch kolumnach.
NATURALNE DOŁĄCZENIE
Inne odpowiedzi wymieniały ten „JOIN type” osobno, ale to nie ma sensu. Jest to po prostu składniowa forma cukru dla equi JOIN, która jest specjalnym przypadkiem Theta-JOIN lub INNER JOIN. NATURAL JOIN po prostu zbiera wszystkie kolumny wspólne dla obu tabel, które są łączone i łączy USING()te kolumny. Co rzadko kiedy jest przydatne, z powodu przypadkowych dopasowań (takich jak LAST_UPDATEkolumny w bazie danych Sakila ).
Oto składnia:
SELECT*FROM actor
NATURALJOIN film_actor
NATURALJOIN film
DOŁĄCZ DO ZEWNĘTRZNEJ
Teraz OUTER JOINróżni się nieco od INNER JOINtego, że tworzy UNIONkilka kartezjańskich produktów. Możemy pisać:
-- Convenient syntax:SELECT*FROM a LEFTJOIN b ON<predicate>-- Cumbersome, equivalent syntax:SELECT a.*, b.*FROM a JOIN b ON<predicate>UNIONALLSELECT a.*,NULL,NULL,...,NULLFROM a
WHERENOTEXISTS(SELECT*FROM b WHERE<predicate>)
Nikt nie chce pisać tego drugiego, więc piszemy OUTER JOIN(co zwykle jest lepiej zoptymalizowane przez bazy danych).
Słowo INNERkluczowe OUTERjest tutaj opcjonalne.
OUTER JOIN występuje w trzech smakach:
LEFT [ OUTER ] JOIN: Lewa tabela JOINwyrażenia jest dodawana do unii, jak pokazano powyżej.
RIGHT [ OUTER ] JOIN: Prawa tabela JOINwyrażenia jest dodawana do unii, jak pokazano powyżej.
FULL [ OUTER ] JOIN: Obie tabele JOINwyrażenia są dodawane do unii, jak pokazano powyżej.
Istnieje kilka historycznych, przestarzałych składni w Oracle i SQL Server, które były obsługiwane OUTER JOINjuż zanim standard SQL miał taką składnię:
-- OracleSELECT*FROM actor a, film_actor fa, film f
WHERE a.actor_id = fa.actor_id(+)AND fa.film_id = f.film_id(+)-- SQL ServerSELECT*FROM actor a, film_actor fa, film f
WHERE a.actor_id *= fa.actor_id
AND fa.film_id *= f.film_id
Powiedziawszy to, nie używaj tej składni. Po prostu wymienię to tutaj, abyś mógł rozpoznać go ze starych postów na blogu / starszego kodu.
Podzielony na partycje OUTER JOIN
Niewiele osób wie o tym, ale standard SQL określa partycjonowanie OUTER JOIN(a Oracle to implementuje). Możesz pisać takie rzeczy:
WITH-- Using CONNECT BY to generate all dates in January
days(day)AS(SELECT DATE '2017-01-01'+ LEVEL -1FROM dual
CONNECTBY LEVEL <=31),-- Our departments
departments(department, created_at)AS(SELECT'Dept 1', DATE '2017-01-10'FROM dual UNIONALLSELECT'Dept 2', DATE '2017-01-11'FROM dual UNIONALLSELECT'Dept 3', DATE '2017-01-12'FROM dual UNIONALLSELECT'Dept 4', DATE '2017-04-01'FROM dual UNIONALLSELECT'Dept 5', DATE '2017-04-02'FROM dual
)SELECT*FROM days
LEFTJOIN departments
PARTITIONBY(department)-- This is where the magic happensON day >= created_at
Części wyniku:
+--------+------------+------------+
| day | department | created_at |
+--------+------------+------------+
| Jan 01 | Dept 1 | | -- Didn't match, but still get row
| Jan 02 | Dept 1 | | -- Didn't match, but still get row
| ... | Dept 1 | | -- Didn't match, but still get row
| Jan 09 | Dept 1 | | -- Didn't match, but still get row
| Jan 10 | Dept 1 | Jan 10 | -- Matches, so get join result
| Jan 11 | Dept 1 | Jan 10 | -- Matches, so get join result
| Jan 12 | Dept 1 | Jan 10 | -- Matches, so get join result
| ... | Dept 1 | Jan 10 | -- Matches, so get join result
| Jan 31 | Dept 1 | Jan 10 | -- Matches, so get join result
Chodzi o to, że wszystkie rzędy od podzielonej strony złączenia skończą się w wyniku, niezależnie od tego, czy JOINpasują coś po „drugiej stronie DOŁĄCZENIA”. Krótka historia: ma to na celu uzupełnienie rzadkich danych w raportach. Bardzo przydatne!
SEMI DOŁĄCZ
Poważnie? Nie ma innej odpowiedzi? Oczywiście nie, ponieważ nie ma natywnej składni w SQL, niestety (podobnie jak poniżej ANTI JOIN). Ale możemy użyć IN()i EXISTS()np. Znaleźć wszystkich aktorów, którzy grali w filmach:
SELECT*FROM actor a
WHEREEXISTS(SELECT*FROM film_actor fa
WHERE a.actor_id = fa.actor_id
)
WHERE a.actor_id = fa.actor_idOrzecznik działa jako semi dołączyć orzeczenie. Jeśli w to nie wierzysz, sprawdź plany wykonania, np. W Oracle. Zobaczysz, że baza danych wykonuje operację SEMI JOIN, a nie EXISTS()predykat.
SELECT*FROM actor a
WHERENOTEXISTS(SELECT*FROM film_actor fa
WHERE a.actor_id = fa.actor_id
)
Niektórzy ludzie (szczególnie MySQL) również piszą ANTI JOIN w następujący sposób:
SELECT*FROM actor a
LEFTJOIN film_actor fa
USING(actor_id)WHERE film_id ISNULL
Myślę, że historycznym powodem jest wydajność.
POŁĄCZENIE BOCZNE
OMG, ten jest za fajny. Tylko ja o tym wspominam? Oto fajne zapytanie:
SELECT a.first_name, a.last_name, f.*FROM actor AS a
LEFTOUTERJOIN LATERAL (SELECT f.title, SUM(amount)AS revenue
FROM film AS f
JOIN film_actor AS fa USING(film_id)JOIN inventory AS i USING(film_id)JOIN rental AS r USING(inventory_id)JOIN payment AS p USING(rental_id)WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!GROUPBY f.film_id
ORDERBY revenue DESC
LIMIT 5)AS f
ON true
Znajduje TOP 5 filmów generujących dochód na aktora. Za każdym razem, gdy potrzebujesz zapytania TOP-N-per-coś, LATERAL JOINstanie się Twoim przyjacielem. Jeśli jesteś osobą korzystającą z programu SQL Server, znasz ten JOINtyp pod nazwąAPPLY
SELECT a.first_name, a.last_name, f.*FROM actor AS a
OUTERAPPLY(SELECT f.title, SUM(amount)AS revenue
FROM film AS f
JOIN film_actor AS fa ON f.film_id = fa.film_id
JOIN inventory AS i ON f.film_id = i.film_id
JOIN rental AS r ON i.inventory_id = r.inventory_id
JOIN payment AS p ON r.rental_id = p.rental_id
WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!GROUPBY f.film_id
ORDERBY revenue DESC
LIMIT 5)AS f
OK, może to oszustwo, ponieważ wyrażenie LATERAL JOINlub APPLYjest tak naprawdę „skorelowanym podzapytaniem”, które tworzy kilka wierszy. Ale jeśli pozwolimy na „skorelowane podkwerendy”, możemy również mówić o ...
MULTISET
Jest to naprawdę zaimplementowane tylko przez Oracle i Informix (o ile mi wiadomo), ale może być emulowane w PostgreSQL za pomocą tablic i / lub XML oraz w SQL Server za pomocą XML.
MULTISETtworzy skorelowane podzapytanie i zagnieżdża wynikowy zestaw wierszy w zewnętrznym zapytaniu. Poniższe zapytanie wybiera wszystkich aktorów i dla każdego aktora gromadzi filmy w zagnieżdżonej kolekcji:
SELECT a.*, MULTISET (SELECT f.*FROM film AS f
JOIN film_actor AS fa USING(film_id)WHERE a.actor_id = fa.actor_id
)AS films
FROM actor
Jak widać, istnieje więcej rodzajów JOIN niż tylko „Boring” INNER, OUTERi CROSS JOINktóre zazwyczaj są wymienione. Więcej szczegółów w moim artykule . I proszę, przestańcie używać diagramów Venna do ich zilustrowania.
Equijoin to szczególny przypadek połączenia theta, w którym theta jest równością. Łączenie Theta jest analogiczne do specjalnego przypadku łączenia wewnętrznego, gdzie on jest porównaniem teta kolumny z każdego z nich. Kilka dekad po tym, jak Codd zdefiniował je, niektóre podręczniki błędnie zdefiniowały łączenie theta jako uogólnienie, które jest analogią łączenia wewnętrznego.
philipxy
@philipxy: Coś konkretnego powinienem zmienić w swojej odpowiedzi? Możesz zasugerować edycję ...
Lukas Eder
10
Stworzyłem, moim zdaniem, ilustrację lepszą niż słowa:
@Niraj Kręgi A i B nie zawierają wierszy A i B. Są one ślepo kopiowane z innych źródeł bez uznania. Łączenie krzyżowe jest uwzględnione w przypadku łączenia wewnętrznego, to połączenie wewnętrzne 1 = 1. W jaki sposób te części obrazu są „idealne”?
philipxy
@philipxy Przepraszam, ale nie przejmuję się tym, czy jest on kopiowany z innego miejsca. i nie jestem pewien, co nie jest poprawne na powyższym zdjęciu. dla mnie to jest w porządku. Łączenie krzyżowe nie jest tu opisane. Nie jest uwzględnione w złączeniu wewnętrznym.
Niraj,
-3
Będę naciskać na mojego zwierzaka: słowo kluczowe USING.
Jeśli obie tabele po obu stronach JOIN mają poprawnie nazwane klucze obce (tj. Tę samą nazwę, a nie tylko „id”), można tego użyć:
Co to jest
SQL JOIN
?SQL JOIN
to metoda pobierania danych z dwóch lub więcej tabel baz danych.Jakie są różne
SQL JOIN
s?Istnieje w sumie pięć
JOIN
sekund. Oni są :1. DOŁĄCZ lub DOŁĄCZ DO WEWNĘTRZNEGO:
W tego rodzaju a
JOIN
otrzymujemy wszystkie rekordy, które pasują do warunków w obu tabelach, a rekordy w obu tabelach, które nie pasują, nie są raportowane.Innymi słowy,
INNER JOIN
opiera się na jednym fakcie, że: TYLKO pasujące pozycje ZARÓWNO MUSZĄ zostać wymienione tabele.Zauważ, że
JOIN
bez żadnych innychJOIN
słów kluczowych (takich jakINNER
,OUTER
,LEFT
itp) jestINNER JOIN
. Innymi słowy,JOIN
jest cukrem syntaktycznym dlaINNER JOIN
(patrz: Różnica między JOIN a INNER JOIN ).2. DOŁĄCZ DO ZEWNĘTRZNEJ:
OUTER JOIN
pobieraAlbo dopasowane wiersze z jednej tabeli i wszystkie wiersze w drugiej tabeli Lub wszystkie wiersze we wszystkich tabelach (nie ma znaczenia, czy istnieje dopasowanie).
Istnieją trzy rodzaje łączenia zewnętrznego:
2.1 LEWE DOŁĄCZENIE ZEWNĘTRZNE lub LEWE DOŁĄCZENIE
To połączenie zwraca wszystkie wiersze z lewej tabeli w połączeniu z pasującymi wierszami z prawej tabeli. Jeśli w prawej tabeli nie ma pasujących kolumn, zwracane są
NULL
wartości.2.2 PRAWE DOŁĄCZENIE DO ZEWNĄTRZ lub PRAWE DOŁĄCZENIE
Te
JOIN
wszystkie powroty wiersze z prawej tabeli w połączeniu z wierszami pasujące Od lewej tabeli. Jeśli w lewej tabeli nie ma pasujących kolumn, zwracane sąNULL
wartości.2.3 PEŁNE DOŁĄCZENIE ZEWNĘTRZNE lub PEŁNE DOŁĄCZENIE
Te
JOIN
kombajnyLEFT OUTER JOIN
iRIGHT OUTER JOIN
. Zwraca wiersze z dowolnej tabeli, gdy warunki są spełnione, i zwracaNULL
wartość, gdy nie ma zgodności.Innymi słowy,
OUTER JOIN
opiera się na fakcie, że: POWINIEN być wymienione TYLKO pasujące wpisy w JEDNEJ tabeli (PRAWO lub LEWO) lub OBIE tabele (PEŁNE).3. NATURALNE DOŁĄCZENIE:
Opiera się na dwóch warunkach:
JOIN
jest wykonana na wszystkich kolumn o tej samej nazwie na rzecz równości.Wydaje się to mieć charakter bardziej teoretyczny, w wyniku czego (prawdopodobnie) większość DBMS nawet nie zadaje sobie trudu poparcia tego.
4. POŁĄCZENIE KRZYŻOWE:
Jest to iloczyn kartezjański dwóch zaangażowanych tabel. Wynik
CROSS JOIN
nie ma sensu w większości sytuacji. Co więcej, nie będziemy tego wcale potrzebować (a przynajmniej potrzebują, by być precyzyjnym).5. DOŁĄCZ DO:
Nie jest to inna forma
JOIN
, raczej jest toJOIN
(INNER
,OUTER
itp) od stołu do siebie.DOŁĄCZENIA oparte na operatorach
W zależności od operatora użytego w
JOIN
klauzuli mogą istnieć dwa typyJOIN
s. Oni są1. Equi DOŁĄCZ:
Dla dowolnego
JOIN
typu (INNER
,OUTER
itp.), Jeśli użyjemy TYLKO operatora równości (=), wtedy powiemy, żeJOIN
jest toEQUI JOIN
.2. Theta DOŁĄCZ:
Jest to to samo,
EQUI JOIN
ale pozwala wszystkim innym operatorom, takim jak>, <,> = itd.źródło
Definicja:
ŁĄCZENIA są sposobem na zapytanie danych połączonych jednocześnie z wielu tabel jednocześnie.
Rodzaje ŁĄCZNIKÓW:
W przypadku RDBMS istnieje 5 rodzajów sprzężeń:
Equi-Join: Łączy wspólne rekordy z dwóch tabel w oparciu o warunek równości. Technicznie rzecz biorąc, łączenie wykonane za pomocą operatora równości (=) w celu porównania wartości klucza podstawowego jednej tabeli i wartości klucza obcego innej tabeli, dlatego zestaw wyników zawiera wspólne (dopasowane) rekordy z obu tabel. Wdrożenie patrz INNER-JOIN.
Natural-Join: Jest to ulepszona wersja Equi-Join, w której operacja SELECT pomija duplikat kolumny. Wdrożenie patrz INNER-JOIN
Non-Equi-Join: Jest odwrotnością Equi-join, gdzie warunkiem łączenia jest użycie operatora innego niż równy (=) np.! =, <=,> =,>, <Lub MIĘDZY itp. W celu uzyskania informacji na temat implementacji patrz WEWNĘTRZNE ŁĄCZENIE.
Self-Join:: Dostosowane zachowanie złączenia, w którym stół łączy się ze sobą; Jest to zwykle potrzebne do tworzenia zapytań w tabelach z odnośnikami (lub jednostkową jednostką relacji). Aby zapoznać się z implementacją, zobacz WEWNĘTRZNE ŁĄCZENIA.
Produkt kartezjański: krzyż łączy wszystkie rekordy obu tabel bez żadnych warunków. Technicznie zwraca zestaw wyników zapytania bez klauzuli WHERE.
Zgodnie z troską i postępem SQL istnieją 3 typy sprzężeń, a wszystkie sprzężenia RDBMS można uzyskać za pomocą tych rodzajów sprzężeń.
INNER-JOIN: Łączy (lub łączy) dopasowane wiersze z dwóch tabel. Dopasowywanie odbywa się na podstawie wspólnych kolumn tabel i ich operacji porównywania. Jeżeli warunek oparty jest na równości, wówczas: Wykonano EQUI-JOIN, w innym przypadku Non-EQUI-Join.
OUTER-JOIN: Łączy (lub łączy) dopasowane wiersze z dwóch tabel i niepasujące wiersze z wartościami NULL. Można jednak dostosować wybór niepasujących wierszy, np. Wybierając niepasujący wiersz z pierwszej tabeli lub drugiej tabeli według podtypów: POŁĄCZENIE ZEWNĘTRZNE i POŁĄCZENIE ZEWNĘTRZNE.
2.1 LEFT Outer JOIN (aka, LEFT-JOIN): Zwraca tylko dopasowane wiersze z dwóch tabel i niepasujące tylko z tabeli LEFT (tj. Pierwszej tabeli).
2.2 RIGHT Outer JOIN (aka, RIGHT-JOIN): Zwraca dopasowane wiersze z dwóch tabel i niepasujące tylko z prawej tabeli.
2.3 FULL OUTER JOIN (alias OUTER JOIN): Zwraca dopasowane i niepasujące z obu tabel.
CROSS-JOIN: To połączenie nie łączy się / nie łączy, lecz tworzy produkt kartezjański.
Uwaga: Self-JOIN można osiągnąć za pomocą INNER-JOIN, OUTER-JOIN i CROSS-JOIN na podstawie wymagań, ale tabela musi łączyć się ze sobą.
Po więcej informacji:
Przykłady:
1.1: INNER-JOIN: Implementacja Equi-join
1.2: INNER-JOIN: Implementacja Natural-JOIN
1.3: INNER-JOIN z implementacją NON-Equi-join
1.4: ŁĄCZENIE WEWNĘTRZNE z JAŁOWYM ŁĄCZENIEM
2.1: DOŁĄCZENIE ZEWNĘTRZNE (pełne połączenie zewnętrzne)
2.2: LEWE DOŁĄCZ
2.3: PRAWE DOŁĄCZ
3.1: POŁĄCZENIE KRZYŻOWE
3.2: SKRZYDŁO DOŁĄCZ - Self JOIN
//LUB//
źródło
intersect
/except
/union
; tutaj koła są wierszami zwracanymi przezleft
&right
join
, jak mówią ponumerowane etykiety. Obraz AXB jest nonsensem.cross join
=inner join on 1=1
& jest specjalnym przypadkiem pierwszego diagramu.UNION JOIN
. Teraz jest przestarzały w SQL: 2003.Co ciekawe, większość innych odpowiedzi ma te dwa problemy:
Niedawno napisałem artykuł na ten temat: Prawdopodobnie niepełny, kompleksowy przewodnik po wielu różnych sposobach ŁĄCZENIA tabel w SQL , który streszczę tutaj.
Przede wszystkim: DOŁĄCZY to produkty kartezjańskie
Dlatego diagramy Venna wyjaśniają je tak niedokładnie, ponieważ JOIN tworzy iloczyn kartezjański między dwoma połączonymi tabelami. Wikipedia ładnie to ilustruje:
Składnia SQL dla produktów kartezjańskich to
CROSS JOIN
. Na przykład:Który łączy wszystkie wiersze z jednej tabeli ze wszystkimi wierszami z drugiej tabeli:
Źródło:
Wynik:
Jeśli po prostu napiszemy listę tabel oddzieloną przecinkami, otrzymamy to samo:
INNER JOIN (Theta-JOIN)
Jest
INNER JOIN
to po prostu filtrowany, wCROSS JOIN
którym predykat filtru jest wywoływanyTheta
w algebrze relacyjnej.Na przykład:
Pamiętaj, że słowo kluczowe
INNER
jest opcjonalne (z wyjątkiem MS Access).( spójrz na artykuł, aby zobaczyć przykłady wyników )
DOŁĄCZ DO EQUI
Specjalnym rodzajem Theta-JOIN jest equi JOIN, którego używamy najczęściej. Predykat łączy klucz podstawowy jednej tabeli z kluczem obcym innej tabeli. Jeśli użyjemy bazy danych Sakila do zilustrowania, możemy napisać:
Łączy to wszystkich aktorów z ich filmami.
Lub też w niektórych bazach danych:
USING()
Składnia pozwala na określenie kolumny, które muszą być obecne na obu stronach łączenia tabel operacja i tworzy predykat równości w tych dwóch kolumnach.NATURALNE DOŁĄCZENIE
Inne odpowiedzi wymieniały ten „JOIN type” osobno, ale to nie ma sensu. Jest to po prostu składniowa forma cukru dla equi JOIN, która jest specjalnym przypadkiem Theta-JOIN lub INNER JOIN. NATURAL JOIN po prostu zbiera wszystkie kolumny wspólne dla obu tabel, które są łączone i łączy
USING()
te kolumny. Co rzadko kiedy jest przydatne, z powodu przypadkowych dopasowań (takich jakLAST_UPDATE
kolumny w bazie danych Sakila ).Oto składnia:
DOŁĄCZ DO ZEWNĘTRZNEJ
Teraz
OUTER JOIN
różni się nieco odINNER JOIN
tego, że tworzyUNION
kilka kartezjańskich produktów. Możemy pisać:Nikt nie chce pisać tego drugiego, więc piszemy
OUTER JOIN
(co zwykle jest lepiej zoptymalizowane przez bazy danych).Słowo
INNER
kluczoweOUTER
jest tutaj opcjonalne.OUTER JOIN
występuje w trzech smakach:LEFT [ OUTER ] JOIN
: Lewa tabelaJOIN
wyrażenia jest dodawana do unii, jak pokazano powyżej.RIGHT [ OUTER ] JOIN
: Prawa tabelaJOIN
wyrażenia jest dodawana do unii, jak pokazano powyżej.FULL [ OUTER ] JOIN
: Obie tabeleJOIN
wyrażenia są dodawane do unii, jak pokazano powyżej.Wszystkie one mogą być łączone za pomocą słowa kluczowego
USING()
lubNATURAL
( ja faktycznie miał prawdziwy świat przypadków użycia dotyczącyNATURAL FULL JOIN
niedawno )Alternatywne składnie
Istnieje kilka historycznych, przestarzałych składni w Oracle i SQL Server, które były obsługiwane
OUTER JOIN
już zanim standard SQL miał taką składnię:Powiedziawszy to, nie używaj tej składni. Po prostu wymienię to tutaj, abyś mógł rozpoznać go ze starych postów na blogu / starszego kodu.
Podzielony na partycje
OUTER JOIN
Niewiele osób wie o tym, ale standard SQL określa partycjonowanie
OUTER JOIN
(a Oracle to implementuje). Możesz pisać takie rzeczy:Części wyniku:
Chodzi o to, że wszystkie rzędy od podzielonej strony złączenia skończą się w wyniku, niezależnie od tego, czy
JOIN
pasują coś po „drugiej stronie DOŁĄCZENIA”. Krótka historia: ma to na celu uzupełnienie rzadkich danych w raportach. Bardzo przydatne!SEMI DOŁĄCZ
Poważnie? Nie ma innej odpowiedzi? Oczywiście nie, ponieważ nie ma natywnej składni w SQL, niestety (podobnie jak poniżej ANTI JOIN). Ale możemy użyć
IN()
iEXISTS()
np. Znaleźć wszystkich aktorów, którzy grali w filmach:WHERE a.actor_id = fa.actor_id
Orzecznik działa jako semi dołączyć orzeczenie. Jeśli w to nie wierzysz, sprawdź plany wykonania, np. W Oracle. Zobaczysz, że baza danych wykonuje operację SEMI JOIN, a nieEXISTS()
predykat.ANTI DOŁĄCZ
To jest po prostu przeciwieństwem SEMI JOIN ( należy uważać, aby nie używać
NOT IN
chociaż , jak to ma istotne zastrzeżenie)Oto wszyscy aktorzy bez filmów:
Niektórzy ludzie (szczególnie MySQL) również piszą ANTI JOIN w następujący sposób:
Myślę, że historycznym powodem jest wydajność.
POŁĄCZENIE BOCZNE
OMG, ten jest za fajny. Tylko ja o tym wspominam? Oto fajne zapytanie:
Znajduje TOP 5 filmów generujących dochód na aktora. Za każdym razem, gdy potrzebujesz zapytania TOP-N-per-coś,
LATERAL JOIN
stanie się Twoim przyjacielem. Jeśli jesteś osobą korzystającą z programu SQL Server, znasz tenJOIN
typ pod nazwąAPPLY
OK, może to oszustwo, ponieważ wyrażenie
LATERAL JOIN
lubAPPLY
jest tak naprawdę „skorelowanym podzapytaniem”, które tworzy kilka wierszy. Ale jeśli pozwolimy na „skorelowane podkwerendy”, możemy również mówić o ...MULTISET
Jest to naprawdę zaimplementowane tylko przez Oracle i Informix (o ile mi wiadomo), ale może być emulowane w PostgreSQL za pomocą tablic i / lub XML oraz w SQL Server za pomocą XML.
MULTISET
tworzy skorelowane podzapytanie i zagnieżdża wynikowy zestaw wierszy w zewnętrznym zapytaniu. Poniższe zapytanie wybiera wszystkich aktorów i dla każdego aktora gromadzi filmy w zagnieżdżonej kolekcji:Jak widać, istnieje więcej rodzajów JOIN niż tylko „Boring”
INNER
,OUTER
iCROSS JOIN
które zazwyczaj są wymienione. Więcej szczegółów w moim artykule . I proszę, przestańcie używać diagramów Venna do ich zilustrowania.źródło
Stworzyłem, moim zdaniem, ilustrację lepszą niż słowa:
źródło
Będę naciskać na mojego zwierzaka: słowo kluczowe USING.
Jeśli obie tabele po obu stronach JOIN mają poprawnie nazwane klucze obce (tj. Tę samą nazwę, a nie tylko „id”), można tego użyć:
Uważam to za bardzo praktyczne, czytelne i niezbyt często używane.
źródło