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

Актёры конкретного фильма

Задача

Редактор сайта готовит карточку фильма и просит по-простому: «Дай список актёров, которые снимались в „Academy Dinosaur“ — имя и фамилия. Отсортируй по фамилии, так удобнее вычитывать».

Верни имя и фамилию всех актёров этого фильма.

Схема данных

Учебная база проката dvdrental. Один фильм — много актёров, один актёр — много фильмов. Такую связь «многие-ко-многим» хранят через отдельную связующую таблицу:

  • film(film_id, title, ...) — фильмы.
  • actor(actor_id, first_name, last_name, ...) — актёры.
  • film_actor(film_id, actor_id) — связка: одна строка = один актёр в одном фильме.

Решение

SELECT a.first_name, a.last_name
FROM film f
JOIN film_actor fa ON fa.film_id = f.film_id
JOIN actor a ON a.actor_id = fa.actor_id
WHERE f.title = 'Academy Dinosaur'
ORDER BY a.last_name, a.first_name, a.actor_id;

Разбор

Напрямую соединить film и actor нельзя — у фильма нет колонки с актёром, а у актёра нет колонки с фильмом. Их связывает третья таблица, film_actor, где каждая строка — факт «этот актёр снимался в этом фильме». Это стандартный способ хранить связь «многие-ко-многим», и джойн через неё всегда идёт в два прыжка: filmfilm_actoractor.

Первый JOIN цепляет к фильму все строки связки с его film_id — получаем список actor_id, снимавшихся в фильме. Второй JOIN по actor_id подтягивает уже имена из actor. Фильтр WHERE f.title = 'Academy Dinosaur' сужает всё до одного фильма. Следи за регистром: обычное = в PostgreSQL регистрозависимо, а в нашей базе название хранится именно как Academy Dinosaur — напишешь 'ACADEMY DINOSAUR' или 'academy dinosaur', получишь ноль строк без всякой ошибки. Если регистр в данных заранее неизвестен, выручает регистронезависимый поиск через ILIKE — он разбирается в задаче фильмы со словом «love» в названии. Фильтруем по названию, а не по film_id, потому что id держать в голове неудобно, а движок сам найдёт нужную строку.

Про ORDER BY: сортируем по фамилии, добавляя вторыми ключами имя и actor_id. Зачем три ключа, если просили по фамилии? Ради детерминизма. Если два актёра — однофамильцы, порядок между ними без второго ключа не определён и может «прыгать» между запусками; уникальный actor_id в конце гарантирует стабильный вывод. Разные типы соединений и когда какой нужен — в вопросе виды JOIN и их различия.

Похожая логика связки — в задаче пары «фильм — категория», только там связующая таблица film_category.

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

first_name | last_name
--- | ---
Johnny | Cage
Rock | Dukakis
Christian | Gable
Penelope | Guiness
Mary | Keitel
Oprah | Kilmer
Warren | Nolte
Sandra | Peck
Mena | Temple
Lucille | Tracy

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

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

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

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

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