Список клиентов, которые никогда не сдавали мов ie в топ-5 актеров (Sakila DB) - PullRequest
0 голосов
/ 10 марта 2020

В Sakila DB, как получить список клиентов, которые никогда не сдавали в аренду даже один мов ie из топ-5 актеров (список топ-актеров рассчитывается по объему аренды).

Это то, что я использовал, чтобы найти 5 лучших актеров

SELECT a.actor_id, a.first_name, a.last_name, 
COUNT(r.rental_id) AS rentalVolume
FROM actor a
JOIN film_actor fa ON a.actor_id = fa.actor_id
JOIN film f ON fa.film_id = f.film_id
JOIN inventory i ON f.film_id = i.film_id
JOIN rental r ON i.inventory_id = r.inventory_id
GROUP BY a.actor_id, a.first_name, a.last_name
ORDER BY rentalVolume DESC
LIMIT 5;

Я хочу SELECT customer_id, first_name, last_name, которые никогда не сдавали в аренду мов ie от эти актеры.

Желаемый результат будет примерно таким

Customer Number      First Name        Last Name
      2                 PETER           OLIVIER
      8                 JOHN              DOE
      64                GWEN            LORENZO

1 Ответ

0 голосов
/ 10 марта 2020

Вы можете использовать оператор not exists для поиска клиентов, у которых нет движений ie с топ-5 актерами (чтобы определить, какие из их прокатов являются фильмами с этими актерами, вы можете использовать оператор in ):

select c.costumer_id, c.first_name, c.last_name
from costumers c
where not exists (
 select *
 from rental r
      inner join inventory i on i.inventory_id = r.inventory_id
      inner join film f on f.film_id = i.film_id
      inner join film_actor fa on fa.film_id = f.film_id and
                                  fa.actor_id in (<< Here_goes_your_top_5_actors_query >>)
 where r.costumer_id = c.costumer_id 
)

Это самый прямой и простой для понимания перевод ваших логи c в SQL, но коррелированный подзапрос может привести к очень плохой производительности (особенно, когда большое количество записей участвует). Если этот запрос слишком медленный для вас, вы можете выбрать несколько прокатов, сгруппированных по потребителям, и суммировать их фильмы с одним из этих актеров, возвращая только клиентов с суммой ноль.

Внутренняя теперь соединения должны быть заменены на левые, потому что нас интересуют строки, в которых нет ни одного объекта film_actors, соответствующего 5 лучшим актерам, поэтому внутреннее объединение не возвращает этих клиентов.

select c.costumer_id, c.first_name, c.last_name
from costumer c
     left join rental r on r.costumer_id = c.costumer_id
     left join inventory i on i.inventory_id = r.inventory_id
     left join film_actor fa on fa.film_id = i.film_id and
                                fa.actor_id in (<< Here_goes_your_top_5_actors_query >>)
group by c.costumer_id, c.first_name, c.last_name
having sum(fa.film_id) = 0

PS: в этом более быстром запросе я удалил объединение с фильмами, потому что оно никогда не было необходимым, мы не используем никаких данных из таблицы фильмов, поэтому мы можем напрямую присоединить инвентарь к film_actor.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...