Dit artikel geeft een overzicht van de FULL JOIN
in SQL, evenals enkele basisvoorbeelden.
De SQL FULL JOIN
(of FULL OUTER JOIN
) geeft alle rijen terug, zolang er overeenkomende gegevens in een van de tabellen zijn.
Het is alsof je zowel een links rechts join in één join hebt.
Syntaxis
Je specificeert een volledige join in de FROM
clausule. U kunt ofwel de FULL JOIN
of FULL OUTER JOIN
syntaxis.
De FULL JOIN
. gebruiken syntaxis:
SELECT *
FROM Table1 FULL JOIN Table2
ON Table1.Column = Table2.Column;
De FULL OUTER JOIN
. gebruiken syntaxis:
SELECT *
FROM Table1 FULL OUTER JOIN Table2
ON Table1.Column = Table2.Column;
Beide doen precies hetzelfde. Het is alleen dat de OUTER
zoekwoord is optioneel.
Voorbeelden
Hier zijn enkele voorbeelden om te demonstreren.
Voorbeeldgegevens
Ten eerste zijn hier de tabellen die we voor de voorbeelden zullen gebruiken.
De PetTypes
tafel:
+-------------+-----------+ | PetTypeId | PetType | |-------------+-----------| | 1 | Bird | | 2 | Cat | | 3 | Dog | | 4 | Rabbit | +-------------+-----------+ (4 rows affected)
De Pets
tafel:
+---------+-------------+-----------+-----------+------------+ | 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)
De Owners
tafel:
+-----------+-------------+------------+----------------+-------------------+ | 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] | +-----------+-------------+------------+----------------+-------------------+
Merk op dat:
- De
PetTypeId
kolom van dePets
tabel is een externe sleutel van dePetTypeId
van dePetTypes
tabel (wat de primaire sleutel van die tabel is). - De
OwnerId
kolom van dePets
tabel is een externe sleutel van deOwnerId
kolom van deOwners
tafel.
De volledige join-query
Hier is een voorbeeld van het uitvoeren van een volledige join tegen twee van die tafels.
SELECT
p.PetName,
pt.PetType
FROM Pets p
FULL JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Resultaat:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Tweet | Bird | | Fluffy | Cat | | Scratch | Cat | | Meow | Cat | | Fetch | Dog | | Wag | Dog | | Fluffy | Dog | | Bark | Dog | | NULL | Rabbit | +-----------+-----------+ (9 rows affected)
In dit voorbeeld krijgen we een PetType
waarde die niet overeenkomt met een PetName
. Dit komt omdat er geen konijnen als huisdier zijn. Maar de volledige samenvoeging veroorzaakt Rabbit
te retourneren, ook al is er geen huisdier in de Pets
tafel van dat type. Dit resulteert in een NULL
waarde in de PetName
kolom tegen Rabbit
.
Dit is hetzelfde resultaat dat we zouden hebben gekregen als we een juiste join hadden gebruikt, omdat de PetTypes
tabel staat rechts van de JOIN
trefwoord. Dit zou niet zijn gebeurd met een left join, omdat PetTypes
tabel staat niet links van de JOIN
trefwoord. Als we het opnieuw wilden maken met een left join, zouden we de volgorde van de tabellen moeten veranderen, zodat de PetTypes
tafel was aan de linkerkant van de JOIN
trefwoord.
Dit is wat er gebeurt als we de tabelvolgorde in onze query wijzigen wanneer we een volledige join gebruiken.
SELECT
p.PetName,
pt.PetType
FROM PetTypes pt
FULL JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;
Resultaat:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Tweet | Bird | | Fluffy | Cat | | Scratch | Cat | | Meow | Cat | | Fetch | Dog | | Wag | Dog | | Fluffy | Dog | | Bark | Dog | | NULL | Rabbit | +-----------+-----------+ (9 rows affected)
We krijgen precies hetzelfde resultaat. Dit komt omdat de volledige join alle rijen retourneert, zolang er overeenkomende gegevens in een van de tabellen zijn. Zoals gezegd, is het alsof je een linker en rechter join in één join hebt.
Volledige deelname aan 3 tafels
Hier is een voorbeeld van het uitvoeren van een volledige join op alle drie de tafels.
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;
Resultaat:
+-----------+-----------+----------------+ | 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)
Deze keer hebben we een huisdiereigenaar die geen huisdier heeft, evenals een huisdiertype dat niet aan een huisdier is toegewezen.
Als we de volgorde van de tabellen door elkaar schudden, krijgen we hetzelfde resultaat, hoewel de rijen in een andere volgorde worden weergegeven.
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;
Resultaat:
-----------+-----------+----------------+ | 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)
En als we ze nog een keer door elkaar schudden, krijgen we nog steeds hetzelfde resultaat.
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;
Resultaat:
+-----------+-----------+----------------+ | 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)
Als je je afvraagt waarom de laatste PetOwner
is niet NULL
(zoals de laatste PetName
is), is dat omdat het het resultaat is van een aaneenschakeling van tekenreeksen. Ik gebruikte de T-SQL CONCAT()
functie om de voor- en achternaam van de eigenaar samen te voegen.