Задачи на JOIN в SQL
JOIN·middle

Прокаты с именем клиента и названием фильма

Задача

Первый рабочий тикет от Марины, продакт-менеджера: «В таблице аренд одни числовые id — ни имени клиента, ни названия фильма не видно. Собери человекочитаемый журнал: дата аренды, кто брал и что брал. Дай первые 20 записей по дате, дальше подключим постранично».

Верни rental_id, дату аренды, имя клиента и название фильма.

Схема данных

Учебная база проката dvdrental. Проблема в том, что аренда не знает про фильм напрямую — между ними физическая копия диска:

  • rental(rental_id, rental_date, inventory_id, customer_id, ...) — факт аренды.
  • customer(customer_id, first_name, last_name, ...) — клиенты.
  • inventory(inventory_id, film_id, ...) — конкретные диски на полке; у одного фильма их несколько.
  • film(film_id, title, ...) — каталог фильмов.

Решение

SELECT r.rental_id,
       to_char(r.rental_date, 'YYYY-MM-DD HH24:MI') AS rental_date,
       c.first_name || ' ' || c.last_name AS customer,
       f.title AS film
FROM rental r
JOIN customer c USING (customer_id)
JOIN inventory i USING (inventory_id)
JOIN film f USING (film_id)
ORDER BY r.rental_date, r.rental_id
LIMIT 20;

Разбор

Ключевая мысль: rental не ссылается на film — она ссылается на конкретный диск (inventory_id), а уже диск знает свой film_id. Поэтому напрямую соединить аренду и фильм нельзя, нужна цепочка. Двигаемся по ссылкам как по стрелкам: аренда → клиент (по customer_id), аренда → диск (по inventory_id), диск → фильм (по film_id).

USING (customer_id) — короткая запись для ON r.customer_id = c.customer_id, работает, когда колонка называется одинаково в обеих таблицах. Все три соединения тут — обычные INNER JOIN: если у аренды нет клиента или диска, строка выпадет, но в этой базе ссылки целостны, так что теряем ноль строк. Когда LEFT JOIN может, наоборот, размножить строки, разбирается в вопросе может ли LEFT JOIN вернуть больше строк. А обзор всех типов соединений — в вопросе виды JOIN и их различия.

Оператор || склеивает имя и фамилию в одну колонку — мелочь, но именно такие штрихи превращают технический дамп в отчёт, который не стыдно показать Марине. ORDER BY r.rental_date, r.rental_id даёт детерминированный порядок: если у нескольких аренд совпадёт дата, вторым ключом идёт уникальный rental_id, и LIMIT 20 каждый раз вернёт одну и ту же двадцатку.

Если нужно наоборот — вытащить состав актёров конкретного фильма, — это тоже цепочка джойнов, смотри задачу актёры конкретного фильма.

Ожидаемый результат

rental_id | rental_date | customer | film
--- | --- | --- | ---
1 | 2005-05-24 22:53 | Charlotte Hunter | Blanket Beverly
2 | 2005-05-24 22:54 | Tommy Collazo | Freaky Pocus
3 | 2005-05-24 23:03 | Manuel Murrell | Graduate Lord
4 | 2005-05-24 23:04 | Andrew Purdy | Love Suicides
5 | 2005-05-24 23:05 | Delores Hansen | Idols Snatchers
6 | 2005-05-24 23:08 | Nelson Christenson | Mystic Truman
7 | 2005-05-24 23:11 | Cassandra Walters | Swarm Gold
8 | 2005-05-24 23:31 | Minnie Romero | Lawless Vision
9 | 2005-05-25 00:00 | Ellen Simpson | Matrix Snowman
10 | 2005-05-25 00:02 | Danny Isom | Hanging Deep
… всего строк: 20 (показаны первые 10)

Прорешай такие задачи сам

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

Прорешать в бесплатной песочнице

Смежные задачи

Вопросы по теме