Reputation: 53
Hello I'm currently working on SQL problem that I can't quite figure out. Here is the Schema I'm working with:
Here is the question I am stuck on:
-- 3 Find the first name, last name and total combined film length of Sci-Fi films for every actor. That is the result should list the names of all of the actors (even if an actor has not been in any Sci-Fi films) and the total length of Sci-Fi films they have been in.
So far I have
SELECT actor.first_name, actor.last_name, (SELECT SUM(film.length)
from film
INNER JOIN film_category
ON film.film_id = film_category.film_id
INNER JOIN category
ON film_category.category_id = category.category_id
INNER JOIN film_actor
ON film_actor.film_id = film.film_id
INNER JOIN actor
ON film_actor.actor_id = actor.actor_id
WHERE category.name = 'Sci-fi'
)
from actor
I know I need to group it by actor_id but i'm unable to do this in a select subquery. Anyone have some tips?
Upvotes: 4
Views: 854
Reputation: 11
This should get you exactly what you want, including the part about having actors that aren't in Sci-Fi movies. You can LEFT JOIN on film to include all films the film_actor is in. The additional AND statement works with the LEFT JOIN to include actors not in Sci-Fi movies for your aggregate sum function.
SELECT a.actor_id, a.first_name, a.last_name, sum(f.length) AS length
FROM actor a
INNER JOIN film_actor fa ON fa.actor_id = a.actor_id
INNER JOIN film_category fc ON fc.film_id = fa.film_id
INNER JOIN category c ON c.category_id = fc.category_id
LEFT JOIN film f ON f.film_id = fa.film_id
AND c.name = 'Sci-Fi'
GROUP BY a.actor_id;
Upvotes: 1
Reputation: 48
The top answer here actually is not correct. This will work:
SELECT T1.first_name, T1.last_name, T2.total
FROM
(SELECT a.first_name, a.last_name, a.actor_id
FROM actor a
)
AS T1
LEFT JOIN
(SELECT a.first_name, a.last_name, a.actor_id, SUM( f.length ) AS total, c.name
FROM actor a, film_actor fa, film f, film_category fc, category c
WHERE c.category_id = fc.category_id
AND fc.film_id = f.film_id
AND a.actor_id = fa.actor_id
AND fa.film_id = f.film_id
AND c.name = 'sci-fi'
GROUP BY a.actor_id)
AS T2
ON T1.actor_id = T2.actor_id;
It takes all actors, and combines them with the sci-fi actors and gives the combined screen time for sci-fi movies for all. Test it on your data set, worked for me.
Upvotes: 0
Reputation: 314
There is no need to use a subquery. Aggregate functions work on the entire data set. The 'group by' specifies how to group the data you're aggregating.
select a.actor_id, a.first_name, a.last_name, sum(f.length)
from actor a
left outer join film_actor fa on fa.actor_id = a.actor_id
left outer join film f on f.film_id = fa.film_id
left outer join film_categories fc on fc.film_id = f.film_id
left outer join categories c on c.category_id = fc.category_id
where c.name = 'sci-fi'
group by a.actor_id
;
The outer joins ensure actors with no sci-fi film experience are included in the results by
Upvotes: 4
Reputation: 84
I don't understand what are you need subquery, try this:
SELECT actor.first_name, actor.last_name,SUM(film.length)
from film
INNER JOIN film_category
ON film.film_id = film_category.film_id
INNER JOIN category
ON film_category.category_id = category.category_id
INNER JOIN film_actor
ON film_actor.film_id = film.film_id
INNER JOIN actor
ON film_actor.actor_id = actor.actor_id
WHERE category.name = 'Sci-fi'
GROUP BY actor.actor_id;
Upvotes: 1