JOIN-запросы

Прекрасный способ сделать выборку из нескольких таблиц — это запрос с ключевым словом JOIN. В JOIN-запросе можно указать тип связи между таблицами и условие их объединения.
Тип связи для JOIN может быть указан ключевыми словами FULL, OUTER/INNER, LEFT/RIGHT. Если тип связи явно не указан, то применяется INNER JOIN.
В запросе блок JOIN идёт сразу после блока FROM:
Скопировать кодSQL
SELECT -- Имена столбцов результата Таблица1.ИмяСтолбца1, ... FROM -- Запрашиваем данные ИЗ таблицы Таблица1 Таблица1 -- к результатам из Таблица1 ПРИСОЕДИНИТЬ данные из таблицы Таблица2 JOIN Таблица2 -- Условия объединения ON Таблица1.ИмяСтолбцаN = Таблица2.ИмяСтолбцаM WHERE -- Дополнительные условия
image
Так вы уже умеете, вы делали это в прошлом уроке:
Скопировать кодSQL
SELECT author.name, book.title, book.year FROM author, book WHERE book.year = 1886 AND book.author_id = author.id;
Аналогичный запрос с ключевым словом JOIN выглядит так:
Скопировать кодSQL
SELECT -- ВЫБРАТЬ данные из колонок //указываем имена колонок вместе с именем таблицы// author.name, book.title, book.year FROM -- Запрашиваем данные ИЗ ТАБЛИЦЫ author author -- к результатам ПРИСОЕДИНИТЬ данные из таблицы book JOIN book -- показать только те записи, в которых -- значение поля book.author_id равно значению поля author.id ON book.author_id = author.id WHERE -- из всего найденного показать только те результаты, -- где значение поля book.year равно "1886" book.year = 1886;
Результат обоих запросов будет одинаков:
Скопировать кодSQL
name title year ---------------- --------------------------------------------------- --------- Лев Толстой Власть тьмы, или Коготок увяз, всей птичке пропасть 1886 Антон Чехов О вреде табака 1886 Софья Ковалевская Воспоминания о Джордже Эллиоте 1886
Но только JOIN может без особых ухищрений сделать запрос «SQL, найди мне всех авторов в таблице author, у которых нет ни одной книги в таблице book»: sql SELECT author.id, author.name, author.birth_year FROM author LEFT JOIN book ON book.author_id = author.id WHERE book.title IS NULL;
Результат:
Скопировать кодSQL
id name birth_year -- -------------- ----------- 4 Насон Грядущий 3019
При обработке запроса JOIN в вычислениях участвуют две таблицы, которые условно называют «левая» и «правая». «Левая» — это та, которая вызвана в блоке FROM, «правая» указывается после ключевого слова JOIN.
Запрос JOIN позволяет назначить одну из таблиц «главной», а из другой таблицы вывести данные, связанные с найденными в «главной».
Тип этой связи может быть указан ключевыми словами FULL OUTER, INNER, LEFT, RIGHT. По умолчанию применяется INNER.
Ключевое слово назначает «главной» таблицей «левую» (при LEFT JOIN) или «правую» (при RIGHT JOIN). В примере запроса о писателях без книг «левая» таблица — это author, а «правая» — book.
При запросах FULL OUTER JOIN и INNER JOIN таблицы равнозначны, «главной» нет.
Вот фрагмент базы данных детского сада. В таблице А собраны мальчики, в таблице Б — девочки. Дети одеты в карнавальные костюмы.
Скопировать кодSQL
-- Табл. А Табл. Б id costume id costume -- -------- -- --------- 1 Пират 1 Жучка 2 Снежинка 2 Пират 3 Котик 3 Принцесса 4 Буратино 4 Котик
Дети не очень понимают как себя вести, но воспитатель хочет, чтобы они все вместе начали что-то делать. В зависимости от задач дети будут разбиваться на пары или собираться в какие-то группы.
Скопировать кодSQL
-- вернуть все поля из таблицы TableA SELECT * FROM TableA -- дополнительно запросить данные из таблицы TableB INNER JOIN TableB -- и возвращать записи, в которых -- для значения TableA.costume найдено такое же в TableB.costume ON TableA.costume = TableB.costume; -- Ответ: id costume id costume -- -------- -- --------- 1 Пират 2 Пират 3 Котик 4 Котик
Графическое представление INNER JOIN
image
Скопировать кодSQL
SELECT * FROM TableA FULL OUTER JOIN TableB ON TableA.costume = TableB.costume; -- Ответ: id costume id costume ---- -------- ---- --------- 1 Пират 2 Пират 2 Снежинка null null null null 1 Жучка 3 Котик 4 Котик null null 3 Принцесса 4 Буратино null null
image
Скопировать кодSQL
SELECT * FROM TableA LEFT JOIN TableB ON TableA.costume = TableB.costume; -- Ответ: id costume id costume -- -------- ---- --------- 1 Пират 2 Пират 2 Снежинка null null 3 Котик 4 Котик 4 Буратино null null
image
Скопировать кодSQL
SELECT * FROM TableA RIGHT JOIN TableB ON TableA.costume = TableB.costume; -- Ответ: id costume id costume ---- -------- ---- --------- null null 1 Жучка 1 Пират 2 Пират null null 3 Принцесса 3 Котик 4 Котик
image
В зависимости от конкретной базы синтаксис JOIN-запросов может меняться, но обычно есть возможность выбрать необходимую комбинацию модификаторов LEFT, RIGHT, FULL и OUTER для создания необходимого JOIN-запроса.
image