1341. 电影评分
1341. 电影评分
难度:中等 | 题号:1341 | 链接:1341. 电影评分 - 力扣(LeetCode) | 数据结构:SQL
关联:订单最多的用户(同为「分组计数取 Top-1」)· 分数排名(同为「排名 / 并列处理」)· 部门工资最高的员工(分组最值)· 可对照 SQL原理_02(多表连接 / 排序 /
UNION ALL)。
🎯 问题描述
描述:写一个解决方案,同时完成两件事:
- 找出评论电影数量最多的用户名。若并列,返回字典序较小的用户名。
- 找出 2020 年 2 月里平均评分最高的电影名称。若并列,返回字典序较小的电影名称。
返回结果表的列名为 results。
表:Movies / 表:Users / 表:MovieRating
1 | +---------------+---------+ +---------------+---------+ +---------------+---------+ |
示例 1:
1 | 输入: |
提示:
- 两问结果是两条独立的行,需要把两个查询的结果竖着拼起来 → 用
UNION ALL(不要用UNION,语义上不清、还可能误去重)。 - 「并列取字典序较小」=
ORDER BY 主指标 DESC, 名字 ASC后LIMIT 1,一次排序同时解决并列。 - 第二问要先
WHERE created_at限定在2020-02-01 ~ 2020-02-29,再按电影分组取平均分。 - 每问都要
LIMIT 1—— 子查询里各自排序取一行,外层再UNION ALL。
💻 解题思路
思路1:两个子查询各取 Top-1,再 UNION ALL(用户解法)
核心逻辑
把题目拆成两个互不相干的「Top-1」:① 用户名按「评论电影数」降序、名字升序 → 第一行;② 电影名按「2 月平均评分」降序、名字升序 → 第一行。两者列名都对齐成 results,用 UNION ALL 竖拼。
代码实现
1 | # Write your MySQL query statement below |
📊 性能分析
- 时间复杂度:(两次分组聚合 + 两次排序;排序是主导项)。
- 空间复杂度:(分组哈希表 / 排序临时表)。
思考
COUNT(DISTINCT movie_id)的必要性:(movie_id, user_id)是联合主键,理论上一个用户对同一部电影只有一条记录,COUNT(*)也可行;但写COUNT(DISTINCT movie_id)语义更清晰(「评论了多少部电影」而非「多少条记录」),防御性更强。ORDER BY 主指标 DESC, 名字 ASC是处理「并列取字典序最小」的通用技巧——把并列打平逻辑交给排序,而不是写在WHERE里。- 日期边界用左闭右开:
>= '2020-02-01' AND < '2020-03-01'比BETWEEN ... AND '2020-02-29'更稳(闰年 / 不同月天数都不会错)。 - 括号包裹子查询 +
LIMIT:MySQL 里UNION ALL两侧的ORDER BY ... LIMIT必须用括号包起来,否则会被当成整体排序;若需要最终结果保持两个子查询的顺序,可在外层再套一层排序或依赖 MySQL 实现(题解一般允许)。 UNIONvsUNION ALL:本题两行理论上可能同名(某用户名恰好等于某电影名),用UNION会被误去重 → 必须UNION ALL。
思路2:用窗口函数替代 LIMIT(可扩展写法)
核心逻辑
如果题目改成「两个指标都要输出多个并列结果」或需要在同一查询里做更多排名,可把 ORDER BY ... LIMIT 1 换成 RANK() OVER (ORDER BY 指标 DESC, 名字 ASC) 再筛 rk = 1。本题只需一行,LIMIT 1 已足够,此处仅作对 分数排名 一类题的写法呼应。
代码实现
1 | SELECT name AS results |
思考
- 用了
RANK而非DENSE_RANK:题目要求「并列取一个」,靠名字二次排序已保证唯一,其实ROW_NUMBER()也够;RANK语义上更贴近「第一名」。 - 两套思路本质相同——先算指标,再排序取第一名;区别只是「筛选第一名」用
LIMIT还是rk = 1。
🔗 相关链接
- 所属 MOC:学习-数据结构与算法MOC
- 题集索引:LeetCode题集索引
- 关联概念:SQL原理_02(多表连接 / 排序 / UNION)· SQL原理_03(窗口函数)
- 同类题目:订单最多的用户 · 分数排名 · 部门工资最高的员工
📝 总结
「多个独立 Top-1 拼装」模板:
- 每问单独写「分组 → 排序(主指标 DESC, 次要键用于打平)→
LIMIT 1」,用括号包住ORDER BY ... LIMIT,再用UNION ALL竖拼。 - 三个关键点:① 「并列取字典序最小」交给她
ORDER BY 主指标 DESC, 名字 ASC;② 日期边界用左闭右开;③ 竖拼两个同类结果用UNION ALL(可能同名,别用UNION)。
🔗 题集索引:LeetCode题集索引 · 算法地图:学习-数据结构与算法MOC
📎 同类题:订单最多的用户 · 分数排名 · 部门工资最高的员工 | 概念:SQL原理_02 · SQL原理_03
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 笺札!






