Зарегистрируйтесь, чтобы продолжить обучение

Объединение обработкой пропусков Аналитика на SQL

В предыдущем уроке мы немного затронули четыре разных типа соединений в SQL:

Untitled

В этом уроке мы углубимся в эту тему. Мы продолжим знакомиться с темой разных соединений и уделим больше внимания FULL OUTER JOIN, а также LEFT JOIN и RIGHT JOIN.

INNER JOIN

В прошлом уроке мы подробно рассмотрели INNER JOIN. Он возвращает только те строки, которые имеют совпадения в обеих таблицах по заданным условиям связи. Тип INNER JOIN чаще всего встречается при соединении таблиц. Например, он позволяет получить список всех клиентов, которые совершали заказы:

SELECT customers.customer_name, orders.order_date
FROM customers
INNER JOIN orders
ON customers.customer_id = orders.customer_id;

Untitled

При таком соединении двух таблиц мы теряем записи по тем клиентам, которые присутствуют в таблице customers, но не совершали заказов.

Чтобы не потерять эти записи, нам нужны другие типы соединений.

LEFT JOIN и RIGHT JOIN

Чтобы не потерять записи, нам нужно объединить таблицы customers и orders так, чтобы нам вернулись все записи из customers и сопоставленные записи из orders.

Для этого мы используем оператор LEFT JOIN. Если соответствия между customers и orders не будет найдено, мы вернем NULL на стороне таблицы orders.

В контексте предыдущего запроса, мы можем использовать оператор LEFT JOIN следующим образом:

SELECT
    customers.customer_name,
    orders.order_date
FROM customers
LEFT JOIN orders
    ON customers.customer_id = orders.customer_id;

Как мы видим, синтаксис запроса ничем не отличается от предыдущего, кроме самого оператора JOIN. Сам запрос вернет такую таблицу:

Untitled

Появилась строка с клиентом по имени Sarah. При этом показатель order_date по этому клиенту содержит NULL — то есть Сара не совершала никаких заказов.

Теперь мы можем отделить этого клиента от других, задав специальный фильтр после оператора WHERE:

SELECT
    customers.customer_name,
    orders.order_date
FROM customers
LEFT JOIN orders
    ON customers.customer_id = orders.customer_id
WHERE order_date IS NULL;

Как видите, WHERE order_date IS NULL помогает отфильтровать результаты и вывести только строки, в которых значение order_date равно NULL.

В контексте этого запроса NULL в поле order_date означает, что у клиента не было ни одного заказа. Другими словами, запрос возвращает имена клиентов, которые пока ничего не заказывали:

Untitled

В SQL LEFT JOIN выбирает все записи из левой таблицы и соответствующие записи из правой. Так же работает и RIGHT JOIN, только в обратную сторону — выбирает все записи из правой таблицы и соответствующие записи из левой. Если соответствий там нет, результат будет NULL на стороне левой таблицы.

В нашем случае можно получить список всех заказов и соответствующих клиентов. Чтобы это сделать, присоединим таблицу orders (как правую) к таблице customers (как к левой) по полю customer_id:

SELECT
    customers.customer_name,
    orders.order_date
FROM customers
RIGHT JOIN orders
    ON customers.customer_id = orders.customer_id;

Untitled

Этот запрос аналогичен тому, что мы делали ранее для LEFT JOIN, но таблицы поменялись местами.

Обратите внимание на заказ с датой 2023-01-04 в правой таблице orders. Мы не нашли соответствующего имени клиента customer_name в таблице customers и поэтому вместо имени вернули NULL.

FULL JOIN

В SQL FULL JOIN или FULL OUTER JOIN помогает объединить две таблицы так, чтобы мы получили все записи из обеих таблиц, даже если для них нет соответствующих записей из другой таблицы.

Если нет соответствующих записей, то значения в этих полях будут NULL:

SELECT
    customers.customer_name,
    orders.order_date
FROM customers
FULL JOIN orders
    ON customers.customer_id = orders.customer_id;

Untitled

На примере все того же соединения данных по клиентам из таблицы customers и заказов из таблицы orders, мы можем с помощью FULL JOIN найти, какие клиенты еще не делали заказов, или какие заказы были сделаны клиентами не из нашей базы. Для этого используем фильтрацию WHERE … is NULL по показателю order_date:

SELECT
    customers.customer_name,
    orders.order_date
FROM customers
FULL JOIN orders
    ON customers.customer_id = orders.customer_id
WHERE order_date IS NULL;

Untitled

Также можно отфильтровать по параметру customer_name:

SELECT
    customers.customer_name,
    orders.order_date
FROM customers
FULL JOIN orders
    ON customers.customer_id = orders.customer_id
WHERE customer_name IS NULL;

Untitled

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

Выводы

Кратко рассмотрим основные выводы из этого урока:

  1. INNER JOIN используется для соединения двух таблиц по общему полю так, что в результат попадают только те записи, для которых найдены совпадения в обеих таблицах. Так можно найти взаимосвязи между двумя наборами данных
  2. LEFT JOIN и RIGHT JOIN выбирают все записи из одной таблицы (левой или правой соответственно) и соответствующие записи из другой. Если соответствующих записей нет, вместо них вставляется NULL. Так мы можем увидеть все данные из одной таблицы независимо от наличия сопоставлений в другой
  3. FULL JOIN возвращает все записи из обеих таблиц, даже если нет совпадений. Это полезно для получения полного набора данных из обеих таблиц и идентификации записей, которые есть только в одной из них

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff