题目描述
(通过次数6,596 | 提交次数16,080,通过率41.02%)
表:Movies +---------------+---------+ | Column Name | Type | +---------------+---------+ | movie_id | int | | title | varchar | +---------------+---------+ movie_id 是这个表的主键。 title 是电影的名字。 表:Users +---------------+---------+ | Column Name | Type | +---------------+---------+ | user_id | int | | name | varchar | +---------------+---------+ user_id 是表的主键。 表:MovieRating +---------------+---------+ | Column Name | Type | +---------------+---------+ | movie_id | int | | user_id | int | | rating | int | | created_at | date | +---------------+---------+ (movie_id, user_id) 是这个表的主键。 这个表包含用户在其评论中对电影的评分 rating 。 created_at 是用户的点评日期。 请你编写一组SQL 查询: 查找评论电影数量最多的用户名。如果出现平局,返回字典序较小的用户名。 查找在 February 2020 平均评分最高 的电影名称。如果出现平局,返回字典序较小的电影名称。 字典序 ,即按字母在字典中出现顺序对字符串排序,字典序较小则意味着排序靠前。 查询结果格式如下例所示。 示例: 输入: Movies 表: +-------------+--------------+ | movie_id | title | +-------------+--------------+ | 1 | Avengers | | 2 | Frozen 2 | | 3 | Joker | +-------------+--------------+ Users 表: +-------------+--------------+ | user_id | name | +-------------+--------------+ | 1 | Daniel | | 2 | Monica | | 3 | Maria | | 4 | James | +-------------+--------------+ MovieRating 表: +-------------+--------------+--------------+-------------+ | movie_id | user_id | rating | created_at | +-------------+--------------+--------------+-------------+ | 1 | 1 | 3 | 2020-01-12 | | 1 | 2 | 4 | 2020-02-11 | | 1 | 3 | 2 | 2020-02-12 | | 1 | 4 | 1 | 2020-01-01 | | 2 | 1 | 5 | 2020-02-17 | | 2 | 2 | 2 | 2020-02-01 | | 2 | 3 | 2 | 2020-03-01 | | 3 | 1 | 3 | 2020-02-22 | | 3 | 2 | 4 | 2020-02-25 | +-------------+--------------+--------------+-------------+ 输出: Result 表: +--------------+ | results | +--------------+ | Daniel | | Frozen 2 | +--------------+ 解释: Daniel 和 Monica 都点评了 3 部电影("Avengers", "Frozen 2" 和 "Joker") 但是 Daniel 字典序比较小。 Frozen 2 和 Joker 在 2 月的评分都是 3.5,但是 Frozen 2 的字典序比较小。 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/movie-rating
//测试数据 Create table If Not Exists Movies (movie_id int, title varchar(30)); Create table If Not Exists Users (user_id int, name varchar(30)); Create table If Not Exists MovieRating (movie_id int, user_id int, rating int, created_at date); insert into Movies (movie_id, title) values ('1', 'Avengers'); insert into Movies (movie_id, title) values ('2', 'Frozen 2'); insert into Movies (movie_id, title) values ('3', 'Joker'); insert into Users (user_id, name) values ('1', 'Daniel'); insert into Users (user_id, name) values ('2', 'Monica'); insert into Users (user_id, name) values ('3', 'Maria'); insert into Users (user_id, name) values ('4', 'James'); insert into MovieRating (movie_id, user_id, rating, created_at) values ('1', '1', '3', '2020-01-12'); insert into MovieRating (movie_id, user_id, rating, created_at) values ('1', '2', '4', '2020-02-11'); insert into MovieRating (movie_id, user_id, rating, created_at) values ('1', '3', '2', '2020-02-12'); insert into MovieRating (movie_id, user_id, rating, created_at) values ('1', '4', '1', '2020-01-01'); insert into MovieRating (movie_id, user_id, rating, created_at) values ('2', '1', '5', '2020-02-17'); insert into MovieRating (movie_id, user_id, rating, created_at) values ('2', '2', '2', '2020-02-01'); insert into MovieRating (movie_id, user_id, rating, created_at) values ('2', '3', '2', '2020-03-01'); insert into MovieRating (movie_id, user_id, rating, created_at) values ('3', '1', '3', '2020-02-22'); insert into MovieRating (movie_id, user_id, rating, created_at) values ('3', '2', '4', '2020-02-25');
解题思路
题目给出了3张源表:一张用户表、一张电影表和一张用户对电影的评分表。这是典型的两张主表+一张关系表的场景。
题目要求返回两部分数据:
第一部分:评论电影数量最多的用户名;
第二部分:2020年2月,平均评分最高的电影名;
很明显,上面的两部分是可以独立查询的。我们只需要分别根据两部分的条件,查询出各自的结果集,然后使用UNION ALL合并即可。
对于第一部分,我们可以先使用GROUP BY+COUNT计算出每个用户评论的电影数量,然后按电影数量倒序排序,返回第一条即可。
第二部分与第一部分类似。只是需要先过滤出2020年2月的评分记录,然后再使用GROUP BY+AVG计算每个电影的平均评分,最后按平均评分倒序排序,返回第一条即可。
最后,合并两部分数据,形成一个结果集返回。
参考SQL
未特别说明的情况下,参考SQL为基于MySQL8.0实现。
with tmp1 as ( select b.name as results from MovieRating a inner join Users b on a.user_id = b.user_id group by a.user_id order by count(1) desc,b.name limit 1 ), tmp2 as ( select b.title from MovieRating a inner join Movies b on a.movie_id = b.movie_id where a.created_at between '2020-02-01' and '2020-02-29' group by a.movie_id order by avg(a.rating) desc,b.title limit 1 ) select * from tmp1 union all select * from tmp2;
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。