Ten artykuł zawiera omówienie FULL JOIN
w SQL, a także kilka podstawowych przykładów.
SQL FULL JOIN
(lub FULL OUTER JOIN
) zwraca wszystkie wiersze, o ile w jednej z tabel znajdują się pasujące dane.
To tak, jakby w jednym sprzężeniu znajdowało się zarówno złącze lewe, prawe.
Składnia
Określasz pełne połączenie w FROM
klauzula. Możesz użyć opcji FULL JOIN
lub FULL OUTER JOIN
składnia.
Korzystanie z FULL JOIN
składnia:
SELECT *
FROM Table1 FULL JOIN Table2
ON Table1.Column = Table2.Column;
Korzystanie z FULL OUTER JOIN
składnia:
SELECT *
FROM Table1 FULL OUTER JOIN Table2
ON Table1.Column = Table2.Column;
Oba robią dokładnie to samo. Po prostu OUTER
słowo kluczowe jest opcjonalne.
Przykłady
Oto kilka przykładów do zademonstrowania.
Przykładowe dane
Najpierw oto tabele, których użyjemy w przykładach.
PetTypes
tabela:
+-------------+-----------+ | PetTypeId | PetType | |-------------+-----------| | 1 | Bird | | 2 | Cat | | 3 | Dog | | 4 | Rabbit | +-------------+-----------+ (4 rows affected)
Pets
tabela:
+---------+-------------+-----------+-----------+------------+ | PetId | PetTypeId | OwnerId | PetName | DOB | |---------+-------------+-----------+-----------+------------| | 1 | 2 | 3 | Fluffy | 2020-11-20 | | 2 | 3 | 3 | Fetch | 2019-08-16 | | 3 | 2 | 2 | Scratch | 2018-10-01 | | 4 | 3 | 3 | Wag | 2020-03-15 | | 5 | 1 | 1 | Tweet | 2020-11-28 | | 6 | 3 | 4 | Fluffy | 2020-09-17 | | 7 | 3 | 2 | Bark | NULL | | 8 | 2 | 4 | Meow | NULL | +---------+-------------+-----------+-----------+------------+ (8 rows affected)
Owners
tabela:
+-----------+-------------+------------+----------------+-------------------+ | OwnerId | FirstName | LastName | Phone | Email | |-----------+-------------+------------+----------------+-------------------| | 1 | Homer | Connery | (308) 555-0100 | [email protected] | | 2 | Bart | Pitt | (231) 465-3497 | [email protected] | | 3 | Nancy | Simpson | (489) 591-0408 | NULL | | 4 | Boris | Trump | (349) 611-8908 | NULL | | 5 | Woody | Eastwood | (308) 555-0112 | [email protected] | +-----------+-------------+------------+----------------+-------------------+
Pamiętaj, że:
PetTypeId
kolumnaPets
tabela jest kluczem obcymPetTypeId
PetTypes
tabela (która jest kluczem podstawowym tej tabeli).OwnerId
kolumnaPets
tabela jest kluczem obcymOwnerId
kolumnaOwners
stół.
Pełne zapytanie przyłączenia
Oto przykład wykonania pełnego sprzężenia przeciwko dwóm z tych tabel.
SELECT
p.PetName,
pt.PetType
FROM Pets p
FULL JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Wynik:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Tweet | Bird | | Fluffy | Cat | | Scratch | Cat | | Meow | Cat | | Fetch | Dog | | Wag | Dog | | Fluffy | Dog | | Bark | Dog | | NULL | Rabbit | +-----------+-----------+ (9 rows affected)
W tym przykładzie otrzymujemy PetType
wartość, która nie odpowiada PetName
. To dlatego, że nie ma królików jako zwierząt domowych. Ale pełne połączenie powoduje, że Rabbit
do zwrotu, nawet jeśli w Pets
nie ma żadnego zwierzaka tabeli tego typu. Powoduje to NULL
wartość w PetName
kolumna przeciwko Rabbit
.
Jest to ten sam wynik, który otrzymalibyśmy, gdybyśmy użyli prawidłowego sprzężenia, ponieważ PetTypes
tabela znajduje się na prawo od JOIN
słowo kluczowe. Nie stałoby się to z lewym złączeniem, ponieważ PetTypes
tabela nie znajduje się po lewej stronie JOIN
słowo kluczowe. Gdybyśmy chcieli odtworzyć go z lewym złączeniem, musielibyśmy zmienić kolejność tabel, tak aby PetTypes
tabela była po lewej stronie JOIN
słowo kluczowe.
Oto, co się stanie, jeśli zmienimy kolejność tabel w naszym zapytaniu podczas korzystania z pełnego sprzężenia.
SELECT
p.PetName,
pt.PetType
FROM PetTypes pt
FULL JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;
Wynik:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Tweet | Bird | | Fluffy | Cat | | Scratch | Cat | | Meow | Cat | | Fetch | Dog | | Wag | Dog | | Fluffy | Dog | | Bark | Dog | | NULL | Rabbit | +-----------+-----------+ (9 rows affected)
Otrzymujemy dokładnie ten sam wynik. Dzieje się tak, ponieważ pełne sprzężenie zwraca wszystkie wiersze, o ile w jednej z tabel znajdują się pasujące dane. Jak wspomniano, to tak, jakby lewe i prawe dołączenie było jednym połączeniem.
Pełne dołączenie na 3 stołach
Oto przykład wykonania pełnego sprzężenia na wszystkich trzech stołach.
SELECT
p.PetName,
pt.PetType,
CONCAT(o.FirstName, ' ', o.LastName) AS PetOwner
FROM Owners o FULL JOIN Pets p
ON p.OwnerId = o.OwnerId
FULL JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Wynik:
+-----------+-----------+----------------+ | PetName | PetType | PetOwner | |-----------+-----------+----------------| | Tweet | Bird | Homer Connery | | Scratch | Cat | Bart Pitt | | Bark | Dog | Bart Pitt | | Fluffy | Cat | Nancy Simpson | | Fetch | Dog | Nancy Simpson | | Wag | Dog | Nancy Simpson | | Fluffy | Dog | Boris Trump | | Meow | Cat | Boris Trump | | NULL | NULL | Woody Eastwood | | NULL | Rabbit | | +-----------+-----------+----------------+ (10 rows affected)
Tym razem mamy właściciela zwierzaka, który nie ma zwierzaka, a także rodzaj zwierzaka, który nie jest przypisany do zwierzaka.
Jeśli przetasujemy kolejność stołów, otrzymamy ten sam wynik, chociaż wiersze są wymienione w innej kolejności.
SELECT
p.PetName,
pt.PetType,
CONCAT(o.FirstName, ' ', o.LastName) AS PetOwner
FROM PetTypes pt FULL JOIN Pets p
ON p.PetTypeId = pt.PetTypeId
FULL JOIN Owners o
ON p.OwnerId = o.OwnerId;
Wynik:
-----------+-----------+----------------+ | PetName | PetType | PetOwner | |-----------+-----------+----------------| | Tweet | Bird | Homer Connery | | Fluffy | Cat | Nancy Simpson | | Scratch | Cat | Bart Pitt | | Meow | Cat | Boris Trump | | Fetch | Dog | Nancy Simpson | | Wag | Dog | Nancy Simpson | | Fluffy | Dog | Boris Trump | | Bark | Dog | Bart Pitt | | NULL | Rabbit | | | NULL | NULL | Woody Eastwood | +-----------+-----------+----------------+ (10 rows affected)
A jeśli ponownie je przetasujemy, nadal uzyskamy ten sam wynik.
SELECT
p.PetName,
pt.PetType,
CONCAT(o.FirstName, ' ', o.LastName) AS PetOwner
FROM Pets p FULL JOIN Owners o
ON p.OwnerId = o.OwnerId
FULL JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Wynik:
+-----------+-----------+----------------+ | PetName | PetType | PetOwner | |-----------+-----------+----------------| | Fluffy | Cat | Nancy Simpson | | Fetch | Dog | Nancy Simpson | | Scratch | Cat | Bart Pitt | | Wag | Dog | Nancy Simpson | | Tweet | Bird | Homer Connery | | Fluffy | Dog | Boris Trump | | Bark | Dog | Bart Pitt | | Meow | Cat | Boris Trump | | NULL | NULL | Woody Eastwood | | NULL | Rabbit | | +-----------+-----------+----------------+ (10 rows affected)
Jeśli zastanawiasz się, dlaczego ostatni PetOwner
nie jest NULL
(jak ostatnio PetName
jest), to dlatego, że jest wynikiem konkatenacji ciągów. Użyłem T-SQL CONCAT()
funkcja łączenia imienia i nazwiska właściciela.