Принципы работы SQL Join: виды, запросы, примеры

Структура реляционных БД подразумевает хранение различных данных в соответствующих таблицах. Часто запросы требуют обращений к нескольким таблицам сразу. Для решения этой задачи существует механизм Join, способный объединять данные из нескольких таблиц.

В этой статье мы подробно рассмотрим, что собой представляет и как работает оператор Join в SQL, а также вас ждет описание разновидностей Join и примеры использования в различных задачах.

Виды Join в SQL

Разберем наиболее популярные типы Join в SQL.

Наглядное сравнение разных типов Join

Inner Join

Inner Join позволяет получить данные из указанных в SQL-запросе таблиц. Рассмотрим пример, в котором нам необходимо сопоставить покупателя и заказ. Укажем в запросе желаемые столбцы и таблицы, из которых необходимо их получить:

SELECT orders.order_id, customers.name, orders.product_name 
FROM customers
JOIN orders

Далее в запросе необходимо явно задать условие: должны быть выведены строки, в которых значение столбца customer_id в таблице customers совпадает со значением столбца customer_id в таблице orders. Для этого добавим оператор ON:

ON customers.customer_id=orders.customer_id;

Итоговый запрос выглядит следующим образом:

SELECT orders.order_id, customers.name, orders.product_name 
FROM customers 
JOIN orders 
ON customers.customer_id = orders.customer_id;

В результате получаем объединенную таблицу “покупатель – заказ”:

+----------+---------------+--------------+
| order_id | name          | product_name |
+----------+---------------+--------------+
|      101 | John Smith    | Laptop       |
|      102 | Emma Johnson  | Smartphone   |
|      103 | John Smith    | Mouse        |
|      104 | Michael Brown | Keyboard     |
|      105 | David Wilson  | Monitor      |
|      106 | Sarah Davis   | Headphones   |
|      107 | John Smith    | Tablet       |
+----------+---------------+--------------+

Если в SQL-запросе вы не указали тип Join, то, как и в примере выше, будет использован Inner Join. В результате будут получены только те строки, данные в которых совпадают в обеих таблицах по заданному критерию.

Однако помимо Inner существуют и другие типы механизма Join, позволяющие получить информацию из таблиц.

Left Join

Left Join возвращает все строки из левой таблицы и совпадающие строки из правой. Если совпадений нет, вместо значений правой таблицы будут выведены NULL.

Это особенно полезно, когда необходимо получить полный список объектов, даже если связанные данные отсутствуют.

Например, выведем всех покупателей, включая тех, кто еще ничего не заказал:

SELECT customers.name, orders.product_name
FROM customers
LEFT JOIN orders
ON customers.customer_id = orders.customer_id;

Результат:

+---------------+--------------+
| name          | product_name |
+---------------+--------------+
| John Smith    | Laptop       |
| Emma Johnson  | Smartphone   |
| John Smith    | Mouse        |
| Michael Brown | Keyboard     |
| David Wilson  | Monitor      |
| Sarah Davis   | Headphones   |
| John Smith    | Tablet       |
| Lisa Anderson | NULL         |
| Alex Lock     | NULL         |
+---------------+--------------+

Покупатели Alex Lock и Lisa Anderson присутствуют в таблице customers, но не имеют заказов, поэтому значение product_name равно NULL.

Right Join

Right Join работает аналогично Left Join, но приоритет отдается правой таблице:

SELECT customers.name, orders.product_name
FROM customers
RIGHT JOIN orders
ON customers.customer_id = orders.customer_id;

В результат попадут все строки из таблицы orders, даже если соответствующего покупателя в таблице customers нет:

+---------------+--------------+
| name          | product_name |
+---------------+--------------+
| John Smith    | Laptop       |
| Emma Johnson  | Smartphone   |
| John Smith    | Mouse        |
| Michael Brown | Keyboard     |
| David Wilson  | Monitor      |
| Sarah Davis   | Headphones   |
| John Smith    | Tablet       |
| NULL          | USB Cable    |
+---------------+--------------+

Full Join

Full Join возвращает все строки из обеих таблиц. Если запись есть в левой таблице, но нет в правой – для столбцов правой таблицы будут выведены NULL. И наоборот: если запись есть в правой таблице, но нет в левой, NULL получат столбцы левой таблицы.

Этот тип объединения удобен, когда нужно найти все несоответствия между таблицами: например, покупателей без заказов и заказы без привязанных покупателей.

Обратите внимание!
В MySQL нет нативной поддержки Full Join. Однако его можно эмулировать с помощью объединения Left Join и Right Join через оператор Union.

Пример SQL-запроса с Full Join:

SELECT customers.name, orders.product_name
FROM customers
FULL JOIN orders
ON customers.customer_id = orders.customer_id;

Для MySQL запрос будет выглядеть так:

SELECT customers.name, orders.order_id, orders.product_name
FROM customers
LEFT JOIN orders
ON customers.customer_id = orders.customer_id
UNION
SELECT customers.name, orders.order_id, orders.product_name
FROM customers
RIGHT JOIN orders
ON customers.customer_id = orders.customer_id;

Оператор Union автоматически удаляет дублирующиеся строки.

Результат запроса:

+---------------+----------+--------------+
| name          | order_id | product_name |
+---------------+----------+--------------+
| John Smith    |      101 | Laptop       |
| Emma Johnson  |      102 | Smartphone   |
| John Smith    |      103 | Mouse        |
| Michael Brown |      104 | Keyboard     |
| David Wilson  |      105 | Monitor      |
| Sarah Davis   |      106 | Headphones   |
| John Smith    |      107 | Tablet       |
| Lisa Anderson |     NULL | NULL         |
| Alex Lock     |     NULL | NULL         |
| NULL          |      108 | USB Cable    |
+---------------+----------+--------------+

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

Self Join

Self Join – это соединение таблицы самой с собой. Такой тип Join используется, когда строки одной таблицы связаны друг с другом. Например, если в таблице сотрудников хранится информация об их руководителях.

Рассмотрим пример таблицы employees, где:

  • id – идентификатор сотрудника
  • name – имя сотрудника
  • manager_id – идентификатор его руководителя

Чтобы сопоставить сотрудников с их менеджерами, используем Self Join и псевдонимы таблицы:

SELECT e.name AS employee, m.name AS manager
FROM employees e
LEFT JOIN employees m
ON e.manager_id = m.id;

В результате получаем:

+---------------+--------------+
| employee      | manager      |
+---------------+--------------+
| John Smith    | NULL         |
| Emma Johnson  | John Smith   |
| Michael Brown | John Smith   |
| Sarah Davis   | Emma Johnson |
+---------------+--------------+

Здесь John Smith является руководителем верхнего уровня – у него нет начальника, поэтому значение manager равно NULL. Остальные сотрудники связаны со своими менеджерами через поле manager_id.

Заключение

Оператор Join – один из ключевых инструментов в SQL.

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

SQL JOIN позволяет объединить данные из разрозненных таблиц в единую картину. Именно поэтому он считается одной из ключевых возможностей SQL при работе с реляционными базами данных.
Надежда Шатило, аналитик в Beget

Если возникнут вопросы, напишите нам, пожалуйста, тикет из панели управления аккаунта (раздел “Помощь и поддержка”), а если вы захотите обсудить синтаксис SQL Join или наши продукты с коллегами по цеху и сотрудниками Beget – ждем вас в нашем сообществе в Telegram.