简体   繁体   中英

How to do multiple tasks in a single SQL query

I was given the database below:

movie(movie_id, movie_name, production_year, votes, ranking, rating)

movie_info(movie_id, movie_genre_id, note)

movie_genre(movie_genre_id, genre_name)

person(person_id, person_name, gender)

role(person_id, movie_id, role_name, role_type_id)

role_type(role_type_id, type_name)

I was asked to display the name of the top 7 directors with at least 3 movies in the list, the number of movies they are in and the average rating of their movies, sorted by the average rating. With the query below I managed to get the name of the directors, the number of movies they are in and the average rating, but I'm having issues limiting it to the top 7 and sorting them by the average rating. I tried using LIMIT and ORDER BY, but I'm getting syntax errors.

SELECT
  person_name, COUNT(role.movie_id), AVG(rating)
FROM
  movie
INNER JOIN
  role
  ON role.movie_id = movie.movie_id
INNER JOIN
  person
  ON role.person_id = person.person_id
INNER JOIN
  role_type
  ON role.role_type_id = role_type.role_type_id
WHERE 
type_name = 'director'
GROUP BY
    person_name
HAVING
  COUNT(role.movie_id) > 2;

I can even order by the number of movies they did and limit it to the top 7, but for God I cannot order it by the AVG(rating)

person_name    COUNT(role.movie_id) AVG(rating)
Hitchcock, Alfred   9               8.2888890372382
Kubrick, Stanley    8               8.2999999523163
Wilder, Billy       6               8.3000000317891
Spielberg, Steven   6               8.4000000953674
Scorsese, Martin    6               8.3166666030884
Nolan, Christopher  6               8.5333331425985
Tarantino, Quentin  6               8.3666666348775
  • In MySQL, Aliases defined in the Select clauses can be used in the Group By , Order By and Having clauses.
  • Use Order by .. DESC to sort the result-set in descending order and Limit 7 to get only 7 rows.
  • You should use proper Aliasing in multi table queries, to avoid ambiguous and unintended behavior.
  • You need to use Group By on person_id also, as there may be cases where director(s) have same name.
  • If you have duplicate entries in role table, you will have to use Count(Distinct ...) to avoid counting duplicate rows.

Try the following query:

SELECT 
  p.person_id,  
  p.person_name, 
  COUNT(r.movie_id) AS movies_count, 
  AVG(m.rating) AS average_rating 
FROM
  movie AS m 
INNER JOIN
  role AS r 
    ON r.movie_id = m.movie_id
INNER JOIN
  person AS p 
    ON r.person_id = p.person_id
INNER JOIN
  role_type AS rt 
    ON r.role_type_id = rt.role_type_id
WHERE 
 rt.type_name = 'director'
GROUP BY 
    p.person_id, 
    p.person_name
HAVING
  movies_count > 2 
ORDER BY 
  movies_count DESC, 
  average_rating DESC 
LIMIT 7

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM