I hope is all well. I am encountering an issue writing SQL query. I did it successfully, however, now I am trying to add explicit JOIN in the query but cant seem to get it or do it properly. Any pointers or tips would be appreciated.
Thank you in advance
SELECT
title,
name,
COUNT(rental_id) AS rental_count
FROM film,
category,
rental,
inventory,
film_category
WHERE film_category.film_id = film.film_id
AND category.category_id = film_category.category_id
AND inventory.film_id = film.film_id
AND rental.inventory_id = inventory.inventory_id
AND name IN ('Animation', 'Children', 'Classics', 'Comedy', 'Family', 'Music')
GROUP BY name,
title
ORDER BY name, title ;
I personally find it much more readable to use the explicit JOIN syntax.
Your query then looks like this:
SELECT title, name, COUNT(rental_id) AS rental_count
FROM film
INNER JOIN inventory ON inventory.film_id = film.film_id
INNER JOIN rental ON rental.inventory_id = inventory.inventory_id
INNER JOIN film_category ON film_category.film_id = film.film_id
INNER JOIN category ON category.category_id = film_category.category_id
WHERE name IN ('Animation', 'Children', 'Classics', 'Comedy', 'Family', 'Music')
GROUP BY name, title
ORDER BY name, title
;
``
You should use JOIN clauses to combine tables, e.g.:
SELECT title
, name
, COUNT(rental_id) AS rental_count
FROM film
JOIN film_category
ON film_category.film_id = film.film_id
JOIN category
ON category.category_id = film_category.category_id
JOIN inventory
ON inventory.film_id = film.film_id
JOIN rental
ON rental.inventory_id = inventory.inventory_id
WHERE name IN ('Animation', 'Children', 'Classics', 'Comedy', 'Family', 'Music')
GROUP BY name
, title
ORDER BY name
, title;
Related
So I'm trying to answer the above question but I'm unable to get the output as, Name of category | Number of times the category was rented.
My code is below,
select c.category_id, sum(r.rental_id) as Rental_count
from category c
inner join film_category fc on fc.category_id = c.category_id
inner join film f on f.film_id = fc.film_id
inner join inventory i on i.film_id = f.film_id
inner join rental r on r.inventory_id = i.inventory_id
group by c.category_id, c.name
order by Rental_count desc
select name as Name, count(rental_id) as Rental_Count
from category
inner join FILM_CATEGORY
using (category_id)
inner join FILM
using (FILM_ID)
inner join inventory
using (FILM_ID)
inner join Rental
using (inventory_id)
group by name
order by count(rental_id) desc
limit 1;
select name, count(rental_id) as Rental_count
from category c
inner join film_category fc on fc.category_id = c.category_id
inner join film f on f.film_id = fc.film_id
inner join inventory i on i.film_id = f.film_id
inner join rental r on r.inventory_id = i.inventory_id
group by c.category_id, c.name
order by Rental_count desc
select Name,count(rental_date) as Rental_count
from category inner join film_category using(category_id)
inner join film using(film_id)
inner join Inventory using(film_id)
inner join Rental using(Inventory_id)
group by category_id,Name
order by Rental_count desc
limit 1;
I am trying to find the correct SQL to perform my task. I am trying to find the count of all actors that all act in the same movie. For all the movies. My SQL statement to fetch the film title and the first and last name of each actor is.
SELECT title, actor.first_name, actor.last_name,
FROM film
INNER JOIN film_actor ON film.film_id = film_actor.film_id
INNER JOIN actor ON film_actor.actor_id = actor.actor_id
ORDER BY film.title
My database returns this :
As you can see there are 10 actors belonging to the movie title ACADEMY DINOSAUR. What is the SQL that would provide me with a number of actors for each film?
Your SQL can be like this
SELECT title, count(1) COUNT
FROM film
INNER JOIN film_actor ON film.film_id = film_actor.film_id
INNER JOIN actor ON film_actor.actor_id = actor.actor_id
GROUP BY title
Pls try this
select tt.title, count(1) from (
SELECT title, actor.first_name, actor.last_name,
FROM film
INNER JOIN film_actor ON film.film_id = film_actor.film_id
INNER JOIN actor ON film_actor.actor_id = actor.actor_id
) tt group by tt.title
ORDER BY tt.title
I'm working with the Sakila sample database, and trying to get the most viewed film per country. So far I've managed to get the most viewed film of a certain country given its id with the following query:
SELECT
F.title, CO.country, count(F.film_id) as times
FROM
customer C
INNER JOIN
address A ON C.address_id = A.address_id
INNER JOIN
city CI ON A.city_id = CI.city_id
INNER JOIN
country CO ON CI.country_id = CO.country_id
INNER JOIN
rental R ON C.customer_id = R.customer_id
INNER JOIN
inventory I ON R.inventory_id = I.inventory_id
INNER JOIN
film F ON I.film_id = F.film_id
WHERE
CO.country_id = 1
GROUP BY
F.film_id
ORDER BY
times DESC
LIMIT 1;
I supose that I'll have to use this query or something similar in the FORM of another query, but I've tried it all I could think and am completely unable to figure out how to do so.
Thanks in advance!
I admit, this is a hell of a query. But well, as long as it works.
Explanation:
Subquery: almost the same as you already has. Without the WHERE and LIMIT. Resulting in a list of movie-count per country
Result of that, grouped per country
GROUP_CONCAT(title ORDER BY times DESC SEPARATOR '|||'), will give ALL titles in that 'row', with the most-viewed title first. The separator doesn't matter, as long as you are sure it will never occurs in a title.
SUBSTRING_INDEX('...', '|||', 1) results in the first part of the string until it finds |||, in this case the first (and thus most-viewed) title
Full query:
SELECT
country_name,
SUBSTRING_INDEX(
GROUP_CONCAT(title ORDER BY times DESC SEPARATOR '|||'),
'|||', 1
) as title,
MAX(times)
FROM (
SELECT
F.title AS title,
CO.country_id AS country_id,
CO.country AS country_name,
count(F.film_id) as times
FROM customer C INNER JOIN address A ON C.address_id = A.address_id
INNER JOIN city CI ON A.city_id = CI.city_id
INNER JOIN country CO ON CI.country_id = CO.country_id
INNER JOIN rental R ON C.customer_id = R.customer_id
INNER JOIN inventory I ON R.inventory_id = I.inventory_id
INNER JOIN film F ON I.film_id = F.film_id
GROUP BY F.film_id, CO.country_id
) AS count_per_movie_per_country
GROUP BY country_id
Proof of concept (as long as the subquery is correct): SQLFiddle
I am writing a query to give actor id, first name, and last name for all actors who have never appeared in a film rated ‘PG’.
Here is what I've done. Can anyone tell me what I did wrong, please?
select distinct actor.actor_id, actor.first_name, actor.last_name
from actor, film, film_actor
where NOT exists
(Select distinct actor.actor_id,actor.first_name,actor.last_name
from actor,film_actor,film
where actor.actor_id = film_actor.actor_id
and film_actor.film_id = film.film_id
and film.rating = 'PG');
The not exists test for a condition and if the condition is true (exists) return false (not exists)
then in you case you get correctly no result
could be you need the actors not in you select
select actor.actor_id, actor.first_name, actor.last_name
from actor
where actor.id NOT in
(Select distinct actor.actor_id
from actor,film_actor,film
where actor.actor_id = film_actor.actor_id
and film_actor.film_id = film.film_id
and film.rating = 'PG');
Following up from the answer above, the line "actor.actor_id = film_actor.actor_id" inside the nested query is not necessary to get the same results. Shorter version:
select distinct a.actor_id, a.first_name, a.last_name from actor a where actor_id NOT IN (select distinct fa.actor_id from film_actor fa, film f where fa.film_id = f.film_id AND f.rating = 'PG');
Using: http://dev.mysql.com/doc/sakila/en/
I'm trying to write a query to count the number of films each actor has acted in by category.
Would appreciate any pointers or advice.
Here is my code so far (it counts the films correctly for one category when I take out the second LEFT JOIN section):
SELECT actor.first_name, actor.last_name,
COUNT(subset.film_id) AS action,
COUNT(subset2.film_id) AS animation
FROM actor
LEFT JOIN (
SELECT film.film_id, actor.actor_id
FROM actor
INNER JOIN film_actor
ON film_actor.actor_id = actor.actor_id
INNER JOIN film
ON film.film_id = film_actor.film_id
INNER JOIN film_category
ON film_category.film_id = film.film_id
INNER JOIN category
ON category.category_id = film_category.category_id
WHERE category.name = 'Action') AS subset
ON subset.actor_id = actor.actor_id
LEFT JOIN (
SELECT film.film_id, actor.actor_id
FROM actor
INNER JOIN film_actor
ON film_actor.actor_id = actor.actor_id
INNER JOIN film
ON film.film_id = film_actor.film_id
INNER JOIN film_category
ON film_category.film_id = film.film_id
INNER JOIN category
ON category.category_id = film_category.category_id
WHERE category.name = 'Animation') AS subset2
ON subset2.actor_id = actor.actor_id
GROUP BY actor.actor_id
ORDER BY actor.last_name ASC;
The query you've got seems awfully complicated if all you want is to get a count of movies per actor and category.
This query:
SELECT
actor.first_name, actor.last_name, category.name,
COUNT(*) as CountPerCategory
FROM actor
JOIN film_actor ON film_actor.actor_id = actor.actor_id
JOIN film ON film.film_id = film_actor.film_id
JOIN film_category ON film_category.film_id = film.film_id
JOIN category ON category.category_id = film_category.category_id
GROUP BY actor.first_name, actor.last_name, category.name;
would give you an output like:
Firstname, Lastname, Category, CountPerCategory
Clint Eastwood Animation 1
Clint Eastwood Action 15
but if you want the counts per category in different columns you could exploit the fact that MySQL returns 1 for true conditions and test that the category matches and use sum (this could also be don't with a case expression in a more portable way), like this:
SELECT
actor.first_name, actor.last_name, category.name
, SUM(category.name = 'Animation') as CountOfAnimation
, SUM(category.name = 'Action') as CountOfAction
FROM actor
JOIN film_actor ON film_actor.actor_id = actor.actor_id
JOIN film ON film.film_id = film_actor.film_id
JOIN film_category ON film_category.film_id = film.film_id
JOIN category ON category.category_id = film_category.category_id
GROUP BY actor.first_name, actor.last_name, category.name;
which would give a result like:
Firstname, Lastname, CountOfAnimation, CountOfAction
Clint Eastwood 1 15
Note that if a film belongs to multiple categories it would get counted once for each category, which might be what you want (or not).
This should give you the count for all actors, with all categories they have been associated with:
SELECT actor.first_name, actor.last_name, category.name
, COUNT(DISTINCT film.film_id)
FROM actor
LEFT JOIN film_actor ON film_actor.actor_id = actor.actor_id
LEFT JOIN film ON film.film_id = film_actor.film_id
LEFT JOIN film_category ON film_category.film_id = film.film_id
LEFT JOIN category ON category.category_id = film_category.category_id
GROUP BY actor.first_name, actor.last_name, category.name
;
If you only want specific ones, add on this after the GROUP BY line:
HAVING category.name IN ('Action', 'Animation')
If you only want actors with those categories, change the LEFT JOINs to INNER JOINs and/or change the aforementioned HAVING to a WHERE (and reposition it accordingly).
I agree, that query looks very complicated and by using 2 derived tables it'll probably run slowly as well. This query will give the unique films in each category and will not duplicate the results as there are no many to many joins.
It will slow down as you add categories however because it has to scan the table multiple times but it will give accurate results and as long as your table isn't too large it should be fine.
You probably don't need the distinct's, but if for whatever reason someone had the same category on a film twice (or something similar) this will remove room for error.
select a.first_name, a.last_name
, (
select count(distinct f.id)
from film f
join film_actor fa on fa.film_id=f.film_id
join film_category fc on fc.film_id=f.film_id
join category c ON c.category_id = fc.category_id
where c.name='Animation'
and fa.actor_id=a.actor_id
) as unique_animation_films
, (
select count(distinct f.id)
from film f
join film_actor fa on fa.film_id=f.film_id
join film_category fc on fc.film_id=f.film_id
join category c ON c.category_id = fc.category_id
where c.name='Action'
and fa.actor_id=a.actor_id
) as unique_action_films
from actor a