Share This
Связаться со мной
Крути в низ
Categories
//Соединения в SQL. Часть 1. Типы соединений и простые примеры

Соединения в SQL. Часть 1. Типы соединений и простые примеры

Соединения — это способ получения данных из нескольких таблиц с помощью SQL. В первой части статьи мы расскажем о типах соединений и рассмотрим несколько базовых примеров.

soedinenija v sql chast 1 tipy soedinenij i prostye primery 67af652 - Соединения в SQL. Часть 1. Типы соединений и простые примеры

Данная статья является переводом. Ссылка на оригинал.

Типы соединений SQL

Тип соединения Описание
INNER JOIN (ВНУТРЕННЕЕ СОЕДИНЕНИЕ) Возвращает те строки, для которых в обеих таблицах выполняется условие соединения.
LEFT JOIN (ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ или просто ЛЕВОЕ СОЕДИНЕНИЕ) Возвращает строки, содержащие данные из левой таблицы (указанной слева от ключевого слова JOIN), даже если в правой таблице нет совпадающих строк. В строках, где нет совпадения справа, все столбцы справа будут заполнены значением NULL.
RIGHT JOIN(ПРАВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ или просто ПРАВОЕ СОЕДИНЕНИЕ) Возвращает строки, содержащие данные из правой таблицы (указанной справа от ключевого слова JOIN), даже если в левой таблице нет совпадающих строк. В строках, где нет совпадения слева, все столбцы слева будут заполнены значением NULL.
FULL JOIN (ПОЛНОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ или просто ПОЛНОЕ СОЕДИНЕНИЕ) Возвращает строки, содержащие данные из обеих таблиц. В строках, где нет совпадения слева или справа, все столбцы без совпадения будут заполнены значением NULL.
CROSS JOIN (ПЕРЕКРЕСТНОЕ СОЕДИНЕНИЕ) Возвращает строки, содержащие все возможные комбинации левой и правой частей соединения. Такое соединение называют «декартовым произведением» (прим. перев.)

Есть еще несколько терминов, которые используются для операций соединения:

Термин Описание
Self-join (самосоединение) Соединение данных в таблице с данными в этой же таблице (с самой собой)
Natural join (естественное соединение) Неявное соединение двух таблиц за счет совпадения имен столбцов в этих таблицах
Equi-join (равнозначное соединение) Соединение двух таблиц, в условии которого используется только операция равенства (=)

Синтаксис соединений

Внутреннее соединение (inner join) может быть описано с помощью предложений FROM или WHERE в операторе SELECT или других операторах DML (data manipulation language, языка манипулирования данными).

Чтобы создать соединение с помощью предложения FROM, нужно поступить следующим образом:

         SELECT * FROM Table1 <JoinType> Table2 [ON (JoinCondition)]      

Здесь конструкция <JoinType> указывает тип соединения, которое мы хотим получить, а JoinCondition – это логическое выражение (предикат), которое должно быть вычислено для каждой пары соединяемых строк.

Чтобы создать соединение с помощью предложения WHERE, напишите так:

         SELECT * FROM Table1, Table2 [WHERE (JoinCondition)]      

В этом случае JoinCondition – это тоже логическое выражение, которое должно быть вычислено для каждой пары соединяемых строк.

Любая часть предложения, заключенная в квадратные скобки [ ], является необязательной.

Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека программиста» Интересно, перейти к каналу

Таблицы данных для наших примеров

Для демонстрации примеров соединений мы будем использовать две таблицы с данными:

  • Таблицу 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)      

Внутреннее соединение (INNER JOIN)

soedinenija v sql chast 1 tipy soedinenij i prostye primery d2602e6 - Соединения в SQL. Часть 1. Типы соединений и простые примеры

Внутреннее соединение (INNER JOIN)

Внутреннее соединение в SQL возвращает строки, для которых в обеих таблицах выполняется условие соединения:

         SELECT 	Pets.PetName, 	PetTypes.PetType FROM Pets INNER JOIN PetTypes ON Pets.PetTypeId = PetTypes.PetTypeId;      

Результат:

         ----------+-----------+ | PetName | PetType   | |---------+-----------| | Fluffy  | Cat       | | Fetch   | Dog       | | Scratch | Cat       | | Wag     | Dog       | | Tweet   | Bird      | | Fluffy  | Dog       | | Bark    | Dog       | | Meow    | Cat       | +---------+-----------+ (8 rows affected)      

Чтобы указать внутренние соединения в предложении FROM, нужно использовать ключевые слова INNER JOIN. Далее после слова ON мы должны описать предикат, соединяющий части строк из наших двух таблиц.

При любом типе соединения нам желательно указывать имена столбцов вместе с именами таблиц, в которых они содержатся. Такой способ записи позволяет избежать неоднозначностей из-за того, что в разных таблицах могут быть столбцы с одинаковыми именами (как в нашем примере). СУБД просто не поймет, из какой таблицы нужно взять столбец. Использование имени таблицы как префикса решит эту проблему. В нашем примере в обеих таблицах есть столбец PetTypeId. В таблице Pets этот столбец используется в качестве внешнего ключа, а в таблице PetTypes – в качестве первичного.

В результате мы получили не все виды питомцев, так как в таблице Pets у нас нет кроликов (rabbit), хотя в таблице PetTypes они есть. Причина в том, что внутреннее соединение возвращает только соединенные строки, для которых условие соединения выполняется в обеих таблицах.

Обратите внимание, что для внутреннего соединения слово INNER часто не является обязательным. Многие (но не все) СУБД позволяют сокращать тип соединения до слова JOIN, что предполагает именно внутреннее соединение таблиц.

Поэтому наш пример мог бы быть записан короче:

         SELECT 	Pets.PetName, 	PetTypes.PetType FROM Pets JOIN PetTypes ON Pets.PetTypeId = PetTypes.PetTypeId;      

Для простоты всё предложение FROM можно записать в одну строку:

         SELECT Pets.PetName, PetTypes.PetType FROM Pets JOIN PetTypes ON Pets.PetTypeId = PetTypes.PetTypeId;      

Статья по теме 🗄️ Базовые запросы SQL: получение записей из БД

Псевдонимы

Часто для сокращения записи соединений используют псевдонимы таблиц. Такую запись становится проще читать.

Например, можно переписать предыдущий запрос так:

         SELECT 	p.PetName, 	pt.PetType FROM Pets p INNER 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       | +----------+-----------+ (8 rows affected)      

Равнозначное соединение

Соединение, показанное выше, называется еще равнозначным соединением. Такое соединение содержит внутри предиката только операции «равно» (=).

Есть и другой способ описать такое соединение:

         SELECT 	p.PetName, 	pt.PetType FROM Pets p, 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       | +-----------+-----------+      

Это пример описания внутреннего соединения с помощью предложения WHERE. Мы указали список таблиц, просто перечислив их через запятую, а условие соединения перенесли в предложение WHERE. Если бы мы не указали такое условие, то мы получили бы перекрестное соединение (cross join).

Многие начинающие считают такой способ записи внутреннего соединения более простым, чем с использованием слов INNER JOIN. Вы вправе выбрать любой из двух вариантов на свой вкус, но учтите, что способ записи с использованием INNER JOIN считается более профессиональным.

Правое соединение (RIGHT JOIN)

soedinenija v sql chast 1 tipy soedinenij i prostye primery d896c7c - Соединения в SQL. Часть 1. Типы соединений и простые примеры

Правое соединение (RIGHT JOIN)

Правое соединение, которое еще называют правым внешним соединением, возвращает строки, в которых всегда есть правая часть (полученная из таблицы, стоящей справа от слова JOIN). Строка будет получена, даже если в левой части не нашлось значений, которые описаны предикатом.

         SELECT 	p.PetName, 	pt.PetType FROM Pets p RIGHT JOIN PetTypes pt ON p.PetTypeId = pt.PetTypeId;      

Результат:

         +-----------+-----------+ | PetName   | PetType   | |-----------+-----------| | Tweet     | Bird      | | Fluffy    | Cat       | | Scratch   | Cat       | | Meow      | Cat       | | Fetch     | Dog       | | Wag       | Dog       | | Fluffy    | Dog       | | Bark      | Dog       | | NULL      | Rabbit    | +-----------+-----------+ (9 rows affected)      

В этом результате мы видим строки с видом «кролик» (rabbit), которых не было в выборке после внутреннего соединения. Напротив слова «Rabbit» в колонке PetName (имя питомца) стоит значение NULL.

Статья по теме 🐬 ТОП-10 самых часто используемых запросов MySQL

Левое соединение (LEFT JOIN)

soedinenija v sql chast 1 tipy soedinenij i prostye primery 80816da - Соединения в SQL. Часть 1. Типы соединений и простые примеры

Левое соединение (LEFT JOIN)

Как и правое соединение, левое соединение называют левым внешним соединением. Оно возвращает строки, в которых всегда есть левая часть (полученная из таблицы, стоящей слева от слова JOIN). Строка будет получена, даже если в правой части не нашлось значений, которые описаны предикатом. Левое соединение по своему смыслу противоположно правому соединению.

Если немного изменить предыдущий пример с использованием левого соединения, то он будет выглядеть так:

         SELECT 	p.PetName, 	pt.PetType FROM Pets p LEFT 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       | +-----------+-----------+ (8 rows affected)      

В этом конкретном случае наш результат совпадает с результатом внутреннего соединения. Однако если мы поменяем местами таблицы в предложении FROM, тогда мы получим такую же выборку, как и при правом соединении.

         SELECT 	p.PetName, 	pt.PetType FROM PetTypes pt LEFT JOIN Pets p ON p.PetTypeId = pt.PetTypeId;      

Результат:

         +-----------+-----------+ | PetName   | PetType   | |-----------+-----------| | Tweet     | Bird      | | Fluffy    | Cat       | | Scratch   | Cat       | | Meow      | Cat       | | Fetch     | Dog       | | Wag       | Dog       | | Fluffy    | Dog       | | Bark      | Dog       | | NULL      | Rabbit    | +-----------+-----------+ (9 rows affected)      

Как видите, разница в результатах между левым и правым соединениями зависит исключительно от того, как вы располагаете таблицы в предложении FROM.

  • 0 views
  • 0 Comment

Leave a Reply

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.

Связаться со мной
Close