⛓️🗄️ Соединения в SQL. Часть 2. Сложные типы соединений
В первой части статьи мы узнали, что такое соединения и рассмотрели простые типы соединений: внутреннее, правое и левое. В заключение рассмотрим более сложные варианты, которые позволяют получать выборки для более интересных случаев.
Полное соединение (FULL JOIN)
Полное соединение (или полное внешнее соединение) возвращает все строки с учетом совпадений, найденных в одной из таблиц. Другими словами, мы получим результат, будто мы применили левое и правое соединения одновременно.
Вот пример полного соединения:
SELECT p.PetName, pt.PetType FROM Pets p FULL JOIN PetTypes pt ON p.PetTypeId = pt.PetTypeId;
Результат:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | | NULL | Rabbit | +-----------+-----------+ (9 rows affected)
Этот запрос возвращает тот же результат, что и при правом соединении, однако он вернул бы другой результат, если бы в левой таблице была строка без соответствующего значения в правой таблице.
Давайте поменяем местами таблицы и запустим его еще раз.
SELECT p.PetName, pt.PetType FROM PetTypes pt FULL JOIN Pets p ON p.PetTypeId = pt.PetTypeId;
Как видите, результат тот же самый. Для полного соединения порядок соединяемых таблиц не имеет значения.
Перекрестное соединение (CROSS JOIN)
Перекрестное соединение возвращает строки, составленные из всех возможных комбинаций левой и правой частей, полученных их соединяемых таблиц. Иначе говоря, оно возвращает декартово произведение (Cartesian product) таблиц, которые участвуют в соединении.
SELECT p.PetName, pt.PetType FROM Pets p CROSS JOIN PetTypes pt;
Результат:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Bird | | Fetch | Bird | | Scratch | Bird | | Wag | Bird | | Tweet | Bird | | Fluffy | Bird | | Bark | Bird | | Meow | Bird | | Fluffy | Cat | | Fetch | Cat | | Scratch | Cat | | Wag | Cat | | Tweet | Cat | | Fluffy | Cat | | Bark | Cat | | Meow | Cat | | Fluffy | Dog | | Fetch | Dog | | Scratch | Dog | | Wag | Dog | | Tweet | Dog | | Fluffy | Dog | | Bark | Dog | | Meow | Dog | | Fluffy | Rabbit | | Fetch | Rabbit | | Scratch | Rabbit | | Wag | Rabbit | | Tweet | Rabbit | | Fluffy | Rabbit | | Bark | Rabbit | | Meow | Rabbit | +-----------+-----------+ (32 rows affected)
Нетрудно себе представить, что такое соединения может быть весьма ресурсоемким, если его выполнить для достаточно больших таблиц. Например, вот так:
SELECT p.PetName, pt.PetType FROM Pets p, PetTypes pt;
Чтобы ограничить размер выборки, в запрос нужно добавить оператор WHERE
, который превратит его во внутреннее соединение:
SELECT p.PetName, pt.PetType FROM Pets p CROSS JOIN PetTypes pt WHERE p.PetTypeId = pt.PetTypeId;
Результат:
+-----------+-----------+ | PetName | PetType | |-----------+-----------| | Fluffy | Cat | | Fetch | Dog | | Scratch | Cat | | Wag | Dog | | Tweet | Bird | | Fluffy | Dog | | Bark | Dog | | Meow | Cat | +-----------+-----------+ (8 rows affected)
Статьи по теме
- 🔤 Азбука SQL в примерах. Часть 1. Создаем базу данных и первую таблицу
- 🐬 ТОП-10 самых часто используемых запросов MySQL
- 📜 15 лучших практик SQL после 20 лет программирования