Актёры конкретного фильма
Задача
Редактор сайта готовит карточку фильма и просит по-простому: «Дай список актёров, которые снимались в „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, где каждая строка — факт «этот актёр снимался в этом фильме». Это стандартный способ хранить связь «многие-ко-многим», и джойн через неё всегда идёт в два прыжка: film → film_actor → actor.
Первый 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
Прорешай такие задачи сам
Читать разбор полезно, а настоящая прокачка — самому писать запросы и получать обратную связь. В симуляторе живая база и проверка запросов, лёгкий режим — бесплатно.
Прорешать в бесплатной песочнице