MySQL查询:如何显示总分排名前5的所有用户(含同分)
解决MySQL中获取总分前5名(含同分)用户的问题
嘿,我来帮你搞定这个需求!首先咱们先优化下你原来的SQL逻辑——原来三次UNION再求和的方式有点冗余,其实可以直接一次计算出用户的总分,然后用窗口函数轻松实现包含同分的前5名筛选。
优化后的完整SQL语句
SELECT user_name, total_points FROM ( SELECT u.user_name, SUM(v.site_point + v.park_point + v.division_point) AS total_points, DENSE_RANK() OVER (ORDER BY SUM(v.site_point + v.park_point + v.division_point) DESC) AS rank_num FROM visits v JOIN users u ON u.user_id = v.user_id GROUP BY u.user_name ) ranked_users WHERE rank_num <= 5 ORDER BY total_points DESC, user_name;
代码解释
- 内层子查询:
- 先关联
visits和users表,通过user_id匹配用户记录。 - 直接计算每个用户的总分:
SUM(v.site_point + v.park_point + v.division_point),这样只需要扫描一次表,比原来三次UNION的效率高很多。 - 用
DENSE_RANK()窗口函数按总分降序排名,这个函数的特点是相同分数的用户会获得相同的排名,且不会跳过后续名次(比如如果有3个用户都是第2名,下一个用户还是第3名,而不是第5名),完美符合你“同分用户全部显示”的需求。
- 先关联
- 外层查询:筛选出排名
<=5的记录,这样就能把所有总分进入前5梯队(包括并列的)的用户都展示出来。 - 最终排序:最后加上
ORDER BY total_points DESC, user_name是为了让结果更规整,同分的用户可以按用户名排序,你也可以换成其他字段(比如user_id)来调整排序逻辑。
为什么不用原来的UNION写法?
原来的三次UNION会重复扫描visits和users表三次,不仅效率低,逻辑也不够简洁。直接一次求和的写法更直观,性能也更优。
内容的提问来源于stack exchange,提问作者Tudoctrine
相关产品推荐
相关产品推荐

