-- List movies with a (rating|revenue) higher than the average (rating|revenue) of all movies.
-- List movies with a rating higher than the average rating of movies in their genre.
-- Find the directors with a career revenue higher than the average revenue of all directors.
-- Find the movies with a rating higher than the average rating of movies released in the same year.
-- Make a super slow query and optimize it as much as we can with what we know so far.
-- List movies with a (rating|revenue) higher
-- than the average (rating|revenue) of all movies.
SELECT title, rating, revenue
FROM movies
WHERE
rating > (SELECT avg(rating) FROM movies) AND
revenue > (SELECT avg(revenue) FROM movies)
#5.2 CTEs
Common Table Expressions - Independent Subqueries๋ฅผ ์ฌ์ฌ์ฉํ ์ ์๊ฒ ํ๋ค.
-- CTE ์์ฑํ๊ธฐ
WITH cte_something AS (SELECT AVG(rating) FROM movies)
-- CTE EX
WITH avg_revenue_cte AS (SELECT AVG(revenue) FROM movies),
avg_rating_cte AS (SELECT AVG(rating) FROM movies)
SELECT
title, director, revenue, rating,
round((SELECT * FROM avg_revenue_cte), 0) AS avg_revenue,
round((SELECT * FROM avg_rating_cte), 0) AS avg_rating
FROM movies
WHERE
revenue > (SELECT avg_revenue FROM avg_revenue_cte) AND
rating > (SELECT avg_rating FROM avg_rating_cte);
-- Find the movies with a rating higher than
-- the average rating of movies released in the same year.
-- Correlated Subquery
SELECT
main_movies.title,
main_movies.director,
main_movies.rating,
main_movies.release_date,
(
SELECT avg(inner_movies.rating)
FROM movies AS inner_movies
WHERE inner_movies.release_date = main_movies.release_date) AS year_average
)
FROM movies AS main_movies
WHERE main_movies.rating > (
SELECT avg(inner_movies.rating)
FROM movies AS inner_movies
WHERE innre_movies.release_date = main_movies.release_date
);
#5.4 Correlated CTEs
WITH movie_avg_per_year AS (
SELECT avg(inner_movies.rating)
FROM movies AS inner_movies
WHERE inner_movies.release_date = main_movies.release_date
)
SELECT
main_movies.title,
main_movies.director,
main_movies.rating,
main_movies.release_date,
(
SELECT *
FROM movie_avg_per_year) AS year_average
)
FROM movies AS main_movies
WHERE main_movies.rating > (
SELECT *
FROM movie_avg_per_year
)
#5.5 Subquery Practice
-- List movies with a rating higher
-- than the average rating of movies in their genre.
WITH avg_rating_genre AS (
SELECT avg(inner_movies.rating)
FROM movies AS inner_movies
WHERE inner_movies.genre = main_movies.genre
)
SELECT title
FROM movies AS main_movies
WHERE main_moveis.rating > (
SELECT *
FROM avg_rating_genre
)
-- Find the directors with a career revenue higher
-- than the average revenue of all directors.
WITH directors_revenues AS (
SELECT sum(revenue) AS career_revenue
FROM movies
WHERE director IS NOT NULL AND revenue IS NOTT NULL
GROUP BY director
), avg_director_carrer_revenue AS (
SELECT avg(career_revenue)
FROM directors_revenues
)
SELECT
director,
sum(revenue) AS total_revenue,
avg_director_carrer_revenue AS peersAVG
FROM movies
WHERE
director IS NOT NULL
AND revenue IS NOT NULL
GROUP BY director
HAVING total_revenue > avg_director_carrer_revenue;
#5.6 Final Practice
WITH director_stats AS (
SELECT
director,
COUNT(*) AS total_movies,
AVG(rating) AS avg_rating,
MAX(rating) AS best_rating,
MIN(rating) AS worst_rating,
MAX(budget) AS highest_budget,
MIN(budget) AS lowest_budget
FROM movies
WHERE director IS NOT NULL AND budget IS NOT NULL AND rating IS NOT NULL
GROUP BY director
)
SELECT
director,
total_movies,
avg_rating,
best_rating,
worst_rating,
highest_budget,
lowest_budget,
(
SELECT title
FROM movies
WHERE rating IS NOT NULL AND budget IS NOT NULL AND director = ds.director
ORDER BY rating DESC
LIMIT 1
) AS best_rated_movie,
(
SELECT title
FROM movies
WHERE rating IS NOT NULL AND budget IS NOT NULL AND director = ds.director
ORDER BY rating ASC
LIMIT 1
) AS worst_rated_movie,
(
SELECT title
FROM movies
WHERE rating IS NOT NULL AND budget IS NOT NULL AND director = ds.director
ORDER BY budget DESC
LIMIT 1
) AS best_expensive_movie,
(
SELECT title
FROM movies
WHERE rating IS NOT NULL AND budget IS NOT NULL AND director = ds.director
ORDER BY rating ASC
LIMIT 1
) AS least_expensive_movie
FROM director_stats AS ds;
-- CREATE INDEX idx_director ON movies (director);
-- DROP INDEX idx_director;