Тази статия предоставя общ преглед на естественото присъединяване в SQL, както и някои основни примери.
Какво е естествено присъединяване?
Естественото свързване на SQL е тип equi-join, което имплицитно комбинира таблици въз основа на колони със същото име и тип. Предикатът за присъединяване възниква имплицитно чрез сравняване на всички колони в двете таблици, които имат еднакви имена на колони в обединените таблици.
Резултатът съдържа само една колона за всяка двойка колони с еднакво име. Ако не бъдат намерени колони със същите имена, резултатът ще бъде кръстосано свързване.
Синтаксис
Естествено свързване може да се приложи към всеки INNER
, LEFT
, RIGHT
или FULL
присъединяване. Просто поставяте префикс на типа на присъединяване с NATURAL
ключова дума.
Пример за синтаксиса, използван за вътрешно съединение:
SELECT *
FROM Table1 NATURAL INNER JOIN Table2
ON Table1.Column = Table2.Column;
Вижда се като INNER
е стойността по подразбиране, можете да го направите и по следния начин:
SELECT *
FROM Table1 NATURAL JOIN Table2
ON Table1.Column = Table2.Column;
NATURAL
ключова дума поставя имплицитно USING
клауза към ограниченията за присъединяване. Той образува USING
списък, състоящ се от всички имена на колони, които се появяват и в двете входни таблици. Това очевидно се отнася само за СУБД, които поддържат USING
клауза.
Не всички СУБД поддържат естествени съединения, така че проверете в документацията на вашата СУБД.
Докато пиша това, естествените съединения се поддържат в PostgreSQL, MySQL, MariaDB, SQLite и Oracle. Естествените обединявания обаче не се поддържат в SQL Server (2019).
Примери
Ето няколко примера за демонстрация.
Примерни данни
Първо, ето таблиците, които ще използваме за примерите.
PetTypes
таблица:
+-------------+-----------+ | PetTypeId | PetType | |-------------+-----------| | 1 | Bird | | 2 | Cat | | 3 | Dog | | 4 | Rabbit | +-------------+-----------+ (4 rows affected)
Pets
таблица:
+---------+-------------+-----------+-----------+------------+ | 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
таблица:
+-----------+-------------+------------+----------------+-------------------+ | 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] | +-----------+-------------+------------+----------------+-------------------+
Имайте предвид, че:
PetTypeId
колона наPets
таблицата е външен ключ наPetTypeId
наPetTypes
таблица (което е първичният ключ на тази таблица).OwnerId
колона наPets
таблицата е външен ключ наOwnerId
колона наOwners
маса.
Пример 1 – Естествено вътрешно съединение
Ето пример за извършване на естествено вътрешно свързване срещу две от тези таблици.
SELECT
PetName,
PetType
FROM Pets
NATURAL JOIN PetTypes;
Резултат:
petname | pettype ---------+--------- Fluffy | Cat Fetch | Dog Scratch | Cat Wag | Dog Tweet | Bird Fluffy | Dog Bark | Dog Meow | Cat (8 rows)
В този пример естественото присъединяване имплицитно присъедини таблиците на двата PetTypeId
колони (т.е. Pets.PetTypeId
колона и PetTypes.PetTypeId
колона).
Това е имплицитен начин да направите следното:
SELECT
PetName,
PetType
FROM Pets
INNER JOIN PetTypes USING (PetTypeId);
Което всъщност прави следното.
SELECT
p.PetName,
pt.PetType
FROM Pets p
INNER JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Пример 2 – Естествено право на присъединяване
Ето пример за извършване на естествено право на присъединяване срещу две от тези таблици. Този път трябва да посочим типа на присъединяване, тъй като не искаме вътрешното присъединяване (по подразбиране).
SELECT
p.PetName,
pt.PetType
FROM Pets p
NATURAL RIGHT JOIN PetTypes pt;
Резултат:
petname | pettype ---------+--------- Fluffy | Cat Fetch | Dog Scratch | Cat Wag | Dog Tweet | Bird Fluffy | Dog Bark | Dog Meow | Cat | Rabbit (9 rows)
В този случай това е същото като да направите следното:
SELECT
p.PetName,
pt.PetType
FROM Pets p
RIGHT JOIN PetTypes pt
ON p.PetTypeId = pt.PetTypeId;
Пример 3 – Естествено пълно присъединяване на 3 маси
Ето пример за извършване на естествено пълно присъединяване и на трите маси.
SELECT
PetName,
PetType,
CONCAT(FirstName, ' ', LastName) AS PetOwner
FROM Owners NATURAL FULL JOIN Pets
NATURAL FULL JOIN PetTypes;
Резултат:
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 | | Woody Eastwood | Rabbit | (10 rows)
Този път имаме собственик на домашен любимец, който няма домашен любимец, както и тип домашен любимец, който не е приписан на домашен любимец.
Пример 4 – Използване на Asterisk (*
) Заместващ знак
Ето пример, който използва заместващия знак звездичка (*), за да изберете всички колони.
SELECT *
FROM Pets
NATURAL JOIN PetTypes;
Резултат:
pettypeid | petid | ownerid | petname | dob | pettype -----------+-------+---------+---------+------------+--------- 2 | 1 | 3 | Fluffy | 2020-11-20 | Cat 3 | 2 | 3 | Fetch | 2019-08-16 | Dog 2 | 3 | 2 | Scratch | 2018-10-01 | Cat 3 | 4 | 3 | Wag | 2020-03-15 | Dog 1 | 5 | 1 | Tweet | 2020-11-28 | Bird 3 | 6 | 4 | Fluffy | 2020-09-17 | Dog 3 | 7 | 2 | Bark | | Dog 2 | 8 | 4 | Meow | | Cat (8 rows)
Имайте предвид, че pettypeid
колоната се връща само веднъж, въпреки че има две колони с това име (по една във всяка таблица). Ето как естествените съединения се справят с колони с едно и също име в таблици.