Этим уроком мы завершаем курс по соединениям в SQL. Здесь мы повторим все ключевые моменты, сравним различные виды соединений между собой, а также проанализируем отличия подзапросов, обобщенных табличных выражений и представлений.
CROSS JOIN
— соединение без условия
Соединение CROSS JOIN
возвращает все возможные сочетания строк из двух таблиц. Схематично это можно представить так:
Число строк в результате — это произведение числа строк в первой и во второй таблице. То есть оно может оказаться очень большим.
На практике редко нужны все возможные сочетания строк, поэтому чаще пользуются соединениями с условием.
Соединения с условием
Соединения INNER JOIN
, LEFT JOIN
, RIGHT JOIN
и FULL OUTER JOIN
содержат условие, которое определяет, какие пары попадут в результат. Между собой операторы отличаются тем, как обрабатываются строки без пары.
Рассмотрим разницу на схеме:
Условие соединения требует, чтобы цвет блоков совпадал. На схеме видно, как разные виды соединений поступают с блоками без пары.
Самый типичный случай использования JOIN
— это связывание таблиц через внешний ключ. Например, работая с таблицей с книгами, мы задействовали еще и таблицу с авторами — сделали на нее ссылку через books.author_id = authors.author_id
. Такие соединения СУБД делает очень эффективно.
Также с помощью соединений можно решать и некоторые специфичные задачи. Рассмотрим такие примеры.
Операция ANTI JOIN
На практике часто бывает задача «найти что-то без чего-то», например:
- Отделы без сотрудников
- Пользователей без сообщений
- Авторов без книг и так далее
Такие задачи эффективно решаются с помощью ANTI JOIN
.
Так схематично выглядит результат:
На этой схеме видно, что из результатов 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 и представления.
Умение использовать соединения — это полезный навык для разработчика. Старайтесь развивать его на практике. Если решили задачу с помощью подзапроса, попробуйте решить ее еще раз с помощью соединения. Пробуйте разные типы соединений, сравнивайте результаты и время выполнения запроса. Так вы научитесь писать самые эффективные запросы.
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.