Работа с несколькими таблицами с помощью подзапросов, JOIN, UNION

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

Подзапросы

Подзапрос это возможность использовать запрос внутри другого запроса для использования его резульата как значение.

Например, у нас есть идентификатор товара равный 100500, номер телефона клиента равный 798755551122 и мы хотим создать заказ для клиента с данным номером телефона.

Для этого сначала нам необходимо понять как получить идентификатор клиента по номеру телефона:

SELECT id FROM customers WHERE phone = "798755551122"

После этого мы можем использовать этот запрос внутри запроса на добавление:

INSERT INTO orders(item_id, customer_id, date_added)
VALUES (100500, (SELECT id FROM customers WHERE phone = "798755551122"), CURRENT_TIMESTAMP) -- CURRENT_TIMESTAMP возвращает текущее время по GMT

Также мы можем работать с результатом в виде списка, например, чтобы использовать его в качестве аргумента WHERE x IN ....

Например я хочу посмотреть список заказов покупателей, чье имя John.

Сначала напишем запрос для получения идентификаторов покупателей с именем John:

SELECT FROM customers WHERE first_name = "John"

Теперь мы можем использовать этот запрос внутри запроса на получение заказов:

SELECT * FROM orders WHERE customer_id in (SELECT FROM customers WHERE first_name = "John")

JOIN

INNER JOIN

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

SELECT a.*, b.название_колонки FROM таблица_а as a
JOIN таблица_б as б ON a.название_колонки = б.название_колонки -- JOIN по умолчанию является INNER JOIN

Запрос выше имеет название INNER JOIN и его задачи найти все данные из таблицы А, найти все данные из таблицы Б и найти их пересечение по условию в блоке ON .... При этом, если у какой-нибудь строки из таблицы А нет пересечения с таблицей Б, то это значение не будет учитываться.

LEFT/RIGHT JOIN

А что если мы хотим, чтобы данные из таблицы А попали в выборку, даже если связь с таблицей Б не найдена ?

Для этого нам на помощью приходит оператор LEFT JOIN.

SELECT a.*, b.название_колонки FROM таблица_а as a
LEFT JOIN таблица_б as б ON a.название_колонки = б.название_колонки

Теперь если данные в таблице А не найдены, то значением b.название_колонки будет NULL.

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

SELECT a.*, b.название_колонки FROM таблица_а as a
RIGHT JOIN таблица_б as б ON a.название_колонки = б.название_колонки

Если в таблице Б у колонки б.название_колонки есть значение, которого нет в таблице А в a.название_колонки, то в качестве a.название_колонки мы увидим NULL.

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

SELECT a.*, b.название_колонки FROM таблица_а as a
JOIN таблица_б as б ON a.название_колонки = б.название_колонки
JOIN таблица_с as с ON б.другая_колонка = с.название_колонки

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

Вернемся к прмеру с получением заказов пользователей с именем John. Мы можем записать этот запрос через оператор JOIN.

SELECT o.*, c.first_name, c.last_name FROM orders as o -- o.* это выборка всех колонок из таблицы имеющей алиас o
JOIN customers as c ON o.customer_id = c.id 
WHERE c.first_name = 'John' 

На данной картинке вы можете подробнее ознакомиться как можно объединять данные друг с другом используя различные виды JOIN и условия

UNION

Если подзапросы дают нам возможность получать значения в динамике, JOIN позволяет объединять данные друг с другом, то UNION служит для объединения результата выборки. По сути это простое объединение результатов различныз таблиц по названию колонок

Синтаксис:

SELECT первая_колонка, воторая колонка FROM таблица_а
UNION SELECT первая_колонка, воторая колонка FROM таблица_б

Если колонки имеют разные нзавания, то зпрос завершится ошибкой. В этом случае стоит вручную задать название. Помимо этого, ошибкой завершится запрос, если количество колонок у таблиц отличается. В этом случае нужно добавить NULL как значение колонок SELECT NULL as название_колонки FROM таблица_а.

Дополнительный материал:

Last updated