Тази статия предоставя общ преглед на FULL JOIN
в SQL, както и някои основни примери.
SQL FULL JOIN
(или FULL OUTER JOIN
) връща всички редове, стига да има съвпадащи данни в една от таблиците.
Това е като да имате и двете ляво дясно присъединяване в едно присъединяване.
Синтаксис
Посочвате пълно присъединяване в FROM
клауза. Можете да използвате или FULL JOIN
или FULL OUTER JOIN
синтаксис.
Използване на FULL JOIN
синтаксис:
SELECT *
FROM Table1 FULL JOIN Table2
ON Table1.Column = Table2.Column;
Използване на FULL OUTER JOIN
синтаксис:
SELECT *
FROM Table1 FULL OUTER JOIN Table2
ON Table1.Column = Table2.Column;
И двете правят абсолютно едно и също нещо. Просто OUTER
ключовата дума не е задължителна.
Примери
Ето няколко примера за демонстрация.
Примерни данни
Първо, ето таблиците, които ще използваме за примерите.
PetTypes
таблица:
+------------+-----------+| PetTypeId | PetType ||-------------+-----------|| 1 | Птица || 2 | Котка || 3 | Куче || 4 | Заек |+------------+-----------+(4 реда засегнати)
Pets
таблица:
+--------+------------+-----------+---------- -+-----------+| PetId | PetTypeId | Id на собственик | Име на домашни любимци | DOB ||---------+------------+-----------+----------- +-----------|| 1 | 2 | 3 | Пухкави | 20.11.2020 || 2 | 3 | 3 | Вземи | 2019-08-16 || 3 | 2 | 2 | Надраскване | 01.10.2018 || 4 | 3 | 3 | Размахване | 2020-03-15 || 5 | 1 | 1 | Tweet | 28.11.2020 || 6 | 3 | 4 | Пухкави | 17.09.2020 || 7 | 3 | 2 | Кора | NULL || 8 | 2 | 4 | Мяу | NULL |+--------+------------+-----------+----------- +-----------+(8 засегнати реда)
Owners
таблица:
+-----------+------------+-----------+------- ---------+------------------+| Id на собственик | Име | Фамилия | Телефон | Имейл ||-----------+------------+-----------+-------- --------+------------------|| 1 | Омир | Конъри | (308) 555-0100 | [email protected] || 2 | Барт | Пит | (231) 465-3497 | [email protected] || 3 | Нанси | Симпсън | (489) 591-0408 | NULL || 4 | Борис | Тръмп | (349) 611-8908 | NULL || 5 | Уди | Истууд | (308) 555-0112 | [email protected] |+-----------+------------+------------+---- ------------+-------------------+
Имайте предвид, че:
PetTypeId
колона наPets
таблицата е външен ключ наPetTypeId
наPetTypes
таблица (което е първичният ключ на тази таблица).OwnerId
колона наPets
таблицата е външен ключ наOwnerId
колона наOwners
маса.
Пълната заявка за присъединяване
Ето пример за извършване на пълно свързване срещу две от тези таблици.
SELECT
p.PetName,
pt.PetType
FROM Pets p
FULL JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Резултат:
+-----------+-----------+| Име на домашни любимци | PetType ||-----------+-----------|| Tweet | Птица || Пухкави | Котка || Надраскване | Котка || Мяу | Котка || Вземи | Куче || Размахване | Куче || Пухкави | Куче || Кора | Куче || NULL | Заек |+-----------+-----------+(9 реда засегнати)
В този пример получаваме PetType
стойност, която не съответства на PetName
. Това е така, защото няма зайци като домашни любимци. Но пълното присъединяване причинява Rabbit
да бъдат върнати, въпреки че в Pets
няма домашен любимец таблица от този тип. Това води до NULL
стойност в PetName
колона срещу Rabbit
.
Това е същият резултат, който бихме получили, ако използвахме правилно присъединяване, защото PetTypes
таблицата е вдясно от JOIN
ключова дума. Това не би се случило с ляво присъединяване, защото PetTypes
таблицата не е отляво на JOIN
ключова дума. Ако искаме да го пресъздадем с ляво присъединяване, ще трябва да променим подредбата на таблиците, така че PetTypes
таблицата беше отляво на JOIN
ключова дума.
Ето какво се случва, ако променим реда на таблицата в нашата заявка, когато използваме пълно присъединяване.
SELECT
p.PetName,
pt.PetType
FROM PetTypes pt
FULL JOIN Pets p
ON p.PetTypeId = pt.PetTypeId;
Резултат:
+-----------+-----------+| Име на домашни любимци | PetType ||-----------+-----------|| Tweet | Птица || Пухкави | Котка || Надраскване | Котка || Мяу | Котка || Вземи | Куче || Размахване | Куче || Пухкави | Куче || Кора | Куче || NULL | Заек |+-----------+-----------+(9 реда засегнати)
Получаваме абсолютно същия резултат. Това е така, защото пълното присъединяване връща всички редове, стига да има съвпадащи данни в една от таблиците. Както споменахме, това е като да имате ляво и дясно присъединяване в едно присъединяване.
Пълно присъединяване на 3 маси
Ето пример за извършване на пълно присъединяване и на трите маси.
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;
Резултат:
+-----------+-----------+----------------+| Име на домашни любимци | PetType | Собственик на домашни любимци ||-----------+----------+----------------|| Tweet | Птица | Хоумър Конъри || Надраскване | Котка | Барт Пит || Кора | Куче | Барт Пит || Пухкави | Котка | Нанси Симпсън || Вземи | Куче | Нанси Симпсън || Размахване | Куче | Нанси Симпсън || Пухкави | Куче | Борис Тръмп || Мяу | Котка | Борис Тръмп || NULL | NULL | Уди Истууд || NULL | Заек | |+----------+-----------+----------------+(10 засегнати реда)предварително>Този път имаме собственик на домашен любимец, който няма домашен любимец, както и тип домашен любимец, който не е приписан на домашен любимец.
Ако разбъркаме подреждането на таблиците, получаваме същия резултат, въпреки че редовете са изброени в различен ред.
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;
Резултат:
----------+-----------+----------------+| Име на домашни любимци | PetType | Собственик на домашни любимци ||-----------+----------+----------------|| Tweet | Птица | Хоумър Конъри || Пухкави | Котка | Нанси Симпсън || Надраскване | Котка | Барт Пит || Мяу | Котка | Борис Тръмп || Вземи | Куче | Нанси Симпсън || Размахване | Куче | Нанси Симпсън || Пухкави | Куче | Борис Тръмп || Кора | Куче | Барт Пит || NULL | Заек | || NULL | NULL | Уди Истууд |+-----------+----------+----------------+(засегнати 10 реда)И ако ги разбъркаме още веднъж, пак получаваме същия резултат.
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;
Резултат:
+-----------+-----------+----------------+| Име на домашни любимци | PetType | Собственик на домашни любимци ||-----------+----------+----------------|| Пухкави | Котка | Нанси Симпсън || Вземи | Куче | Нанси Симпсън || Надраскване | Котка | Барт Пит || Размахване | Куче | Нанси Симпсън || Tweet | Птица | Хоумър Конъри || Пухкави | Куче | Борис Тръмп || Кора | Куче | Барт Пит || Мяу | Котка | Борис Тръмп || NULL | NULL | Уди Истууд || NULL | Заек | |+----------+-----------+----------------+(10 засегнати реда)предварително>Ако се чудите защо последният
PetOwner
не еNULL
(като последнотоPetName
е), защото е резултат от конкатенация на низове. Използвах T-SQLCONCAT()
функция за свързване на името и фамилията на собственика.