Соединение двух таблиц
Соединение (JOIN) складывает вместе строки двух таблиц. Вот вопрос из предыдущего упражнения — кто сделал какой заказ, — но с ответом сразу для всех заказов:
SELECT orders.id, ordered_at, name
FROM orders
JOIN customers ON orders.customer_id = customers.id
ORDER BY orders.id;| id | ordered_at | name |
|---|---|---|
| 1 | 2024-01-20 | Emma Clark |
| 2 | 2024-02-14 | Liam Turner |
| 3 | 2024-02-29 | Olivia Brown |
| 4 | 2024-03-15 | Emma Clark |
| … | … | … |
JOIN customers добавляет в запрос таблицу customers, а условие после ON говорит, какие строки подходят друг другу: заказ связан с тем клиентом, чей id равен customer_id заказа. Это тот самый внешний ключ из предыдущего упражнения, только теперь по нему идёт база данных, а не вы. orders.customer_id — это столбец customer_id таблицы orders: название таблицы, точка и название столбца. В обеих таблицах есть столбец id, поэтому нужно указать, чей именно id вы имеете в виду, — и в ON, и в SELECT. Подробнее об этом вы узнаете в следующем упражнении.
Как база данных находит пары? Можно представить это так: она перебирает строки orders одну за другой и для каждой ищет строки customers, для которых выполняется условие. Каждая найденная пара становится одной строкой результата, где столбцы обеих таблиц стоят рядом, а SELECT потом выбирает, какие из них показать. У заказа 1 customer_id равен 1, условие выполняется для строки Emma Clark, и в результате появляется строка с заказом 1 и Emma Clark. У заказа 4 customer_id тоже 1, поэтому Emma Clark снова попадает в результат, рядом с заказом 4. Так и должно быть: каждый клиент встречается в результате столько раз, сколько у него заказов.
А что с клиентом, у которого нет заказов? Henry Scott ничего не заказывал: ни у одного заказа нет customer_id 12, то есть его id. Его строке не с чем образовать пару, поэтому её в результате нет вообще. JOIN оставляет только строки, нашедшие пару; остальные исчезают. Для списка заказов это именно то, что нужно. Если нужно сохранить и их, есть другой вид соединения, о нём вы узнаете позже в этом уроке.
Вам встретится и INNER JOIN: это то же самое, что JOIN; INNER — просто полное название этого вида соединения. Порядок таблиц не меняет того, какие пары находит JOIN: FROM customers JOIN orders ON … даст те же строки, и то же будет, если поменять местами две части условия по обе стороны от =.
Типичная ошибка — условие, которое связывает не те столбцы. ON orders.id = customers.id выполнится без ошибки, но сопоставит заказ 1 с клиентом 1, заказ 2 с клиентом 2 и так далее, а это ничего не значит. Условие связывает внешний ключ с первичным ключом, на который он указывает: здесь это orders.customer_id и customers.id.
Задание
- 1
Покажите отзывы с названиями игр: соедините
reviewsсgames(game_idотзыва — этоidигры) и покажите столбцыtitle,starsиcomment. Отсортируйте строки поtitle, а отзывы об одной игре — поcustomer_id:title stars comment Bakery Story 4 Cute and calm. Cube Logic 3 NULL Cube Logic 5 Perfect for the bus. Dragon Forge 4 Great story, a bit long. … … … - 2
Ниже напишите запрос, который соединяет
customersсordersи показываетnameкаждого клиента и дату каждого его заказа (ordered_at), отсортированные поname, а затем поordered_at. Henry Scott и Max Baker в нём не окажутся: они ни разу ничего не заказывали.name ordered_at Ava Green 2024-05-11 Ava Green 2025-04-15 Emma Clark 2024-01-20 … …