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

Заключение SQL: Join

Этим уроком мы завершаем курс по соединениям в SQL. Здесь мы повторим все ключевые моменты, сравним различные виды соединений между собой, а также проанализируем отличия подзапросов, обобщенных табличных выражений и представлений.

CROSS JOIN — соединение без условия

Соединение CROSS JOIN возвращает все возможные сочетания строк из двух таблиц. Схематично это можно представить так:

cross-join

Число строк в результате — это произведение числа строк в первой и во второй таблице. То есть оно может оказаться очень большим.

На практике редко нужны все возможные сочетания строк, поэтому чаще пользуются соединениями с условием.

Соединения с условием

Соединения INNER JOIN, LEFT JOIN, RIGHT JOIN и FULL OUTER JOIN содержат условие, которое определяет, какие пары попадут в результат. Между собой операторы отличаются тем, как обрабатываются строки без пары.

Рассмотрим разницу на схеме:

condition-joins

Условие соединения требует, чтобы цвет блоков совпадал. На схеме видно, как разные виды соединений поступают с блоками без пары.

Самый типичный случай использования JOIN — это связывание таблиц через внешний ключ. Например, работая с таблицей с книгами, мы задействовали еще и таблицу с авторами — сделали на нее ссылку через books.author_id = authors.author_id. Такие соединения СУБД делает очень эффективно.

Также с помощью соединений можно решать и некоторые специфичные задачи. Рассмотрим такие примеры.

Операция ANTI JOIN

На практике часто бывает задача «найти что-то без чего-то», например:

  • Отделы без сотрудников
  • Пользователей без сообщений
  • Авторов без книг и так далее

Такие задачи эффективно решаются с помощью ANTI JOIN.

Так схематично выглядит результат:

anti-joins

На этой схеме видно, что из результатов LEFT JOIN или RIGHT JOIN были убраны строки с парой.

Соединение SELF JOIN

Чтобы соединить таблицу с самой собой, мы можем использовать SELF JOIN.

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

Также SELF JOIN используют для поиска потенциальных дубликатов. Задача обычно звучит как «найти разные записи с одинаковым значением некоторого поля». Например, мы можем искать разных пользователей с одинаковым номером телефона или разные книги с одинаковым названием.

Образец такого запроса выглядит так:

SELECT
    A.*,
    B.*
FROM MyTable AS A
INNER JOIN MyTable AS B ON
    A.Id != B.Id AND A.My_Field = B.My_Field

Условие соединения тут требует, чтобы идентификаторы были разными, но значение нужного поля было одинаковым.

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

Альтернативные инструменты

SQL — богатый язык, одну и ту же задачу в нем часто можно решить несколькими способами. Для некоторых задач альтернативное решение можно написать с помощью трех инструментов:

  • Подзапросы — это способ вставить запрос вместо значения или набора значений
  • CTE и представления — это способы выполнить запрос к запросу

Эти инструменты позволяют встроить один SQL-запрос внутрь другого SQL-запроса.

Разберемся, в чем разница между этими инструментами:

  • Результат: CTE и представления формируют виртуальную таблицу, а подзапрос формирует простое значение или набор значений. Тип результата определяет, где и как мы можем воспользоваться инструментом
  • Переиспользование: одно и то же представление можно использовать в разных запросах, а вот подзапросы и CTE доступны только своему основному запросу
  • Зависимость от основного запроса: CTE, представления и некоррелированные подзапросы не зависят от основного запроса — мы можем выполнить их отдельно от него. Коррелированные подзапросы используют значения основного запроса как параметр
  • Особенности выполнения: CTE, представления и некоррелированные подзапросы выполняются не больше одного раза, а коррелированный подзапрос — для каждой строки из основного запроса

Новичкам обычно проще написать решение с использованием подзапроса, представления или CTE, чем с помощью соединения. Однако решение с помощью соединения часто работает быстрее, особенно это касается коррелированных подзапросов.

Выводы

На практике в базах данных почти всегда есть связанные таблицы. И почти всегда эту связь надо реализовывать — одну таблицу надо дополнять связанными данными из других. Соединения — это самый эффективный способ решения таких задач.

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

Умение использовать соединения — это полезный навык для разработчика. Старайтесь развивать его на практике. Если решили задачу с помощью подзапроса, попробуйте решить ее еще раз с помощью соединения. Пробуйте разные типы соединений, сравнивайте результаты и время выполнения запроса. Так вы научитесь писать самые эффективные запросы.

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

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

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

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

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

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

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

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