leetcode mysql 排名_LeetCode-MySQL: 178.分数排名

题目描述

编写一个 SQL 查询来实现分数排名。

如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”。

+----+-------+

| Id | Score |

+----+-------+

| 1 | 3.50 |

| 2 | 3.65 |

| 3 | 4.00 |

| 4 | 3.85 |

| 5 | 4.00 |

| 6 | 3.65 |

+----+-------+

例如,根据上述给定的 Scores 表,你的查询应该返回(按分数从高到低排列):

+-------+------+

| Score | Rank |

+-------+------+

| 4.00 | 1 |

| 4.00 | 1 |

| 3.85 | 2 |

| 3.65 | 3 |

| 3.65 | 3 |

| 3.50 | 4 |

+-------+------+

来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/rank-scores

分析

思考了几分钟,我毫无头绪~,于是我就去看评论,看到一个题解:

select s1.Score, count(distinct(s2.Score)) RankfromScores s1, Scores s2where s1.Score<=s2.Scoregroup bys1.Idorder by Rank;

想了几分钟,有点懵~,s1.Score<=s2.Score 是啥意思?

这个题解有好几个地方不明白是啥意思,当然关键点还是 where s1.Score<=s2.Score 不明白。

接下来我会在本地还原这个题解的执行过程,一步步分析 where s1.Score<=s2.Score 到底做了什么。

创建表 scores

CREATE TABLE`scores` (

`id`int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,

`score`int(3)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

向表 scores 添加一些测试数据

INSERT INTO `scores` (`score`) values (100), (80), (80), (60);

查询scores表,目前共有4条记录

50296ccad706b8cff5e9a9695c5e3334.png

让我们来看看 select * from scores s1, scores s2 的返回结果是什么

509c7441ca54669e3cedc41c400f9b31.png

返回的结果集共有16条记录。

这种多表查询又称 “笛卡尔查询",结果集的列数是s1表和s2表的列数之和,行数是s1表和s2表的行数之积。

到了这里就会自然地想到: select * from scores s1, scores s2 where s1.score <= s2.score 的返回结果是什么呢?

8937ff1444fea667b99a9012a9dbfcdc.png

这个结果是怎么得到的呢?我想到了这里大家应该都知道了

24036bff2903b43fafdc60ff60412fae.png

是的,如上图,左边是s1表,右边是s2表。

现在我们已经知道了 select * from scores s1, scores s2 where s1.score <= s2.score 的返回结果,再进行 group by,order by 和 count() 就很好分析了。

给 scores 表排名:

select s1.score, count(distinct(s2.score)) rank from scores s1, scores s2 where s1.score <= s2.score group by s1.id order by rank

c301dcad68a44ba4ac64a331d426c990.png

group by s1.id:根据 s1.id 进行分组

count(distinct(s2.score)):distinct(s2.score)去重,count(distinct(s2.score))在分组的过程中计算 每个分组 对 s2.score去重后 的记录条数

分析到这里,我们已经清楚排名是怎么计算出来的了。但是,我们可能仍然会有一些疑惑,不禁会想:为什么这样做可以计算出排名?

思考

回想曾经考试后班级的排名,我们是怎么对学生进行排名的呢?

每个人都要和其他所有人进行比较,如果分数比所有人都高,则排第一名。

如下图,

509c7441ca54669e3cedc41c400f9b31.png

8937ff1444fea667b99a9012a9dbfcdc.png

可以看到, s1.score<=s2.score  就是对班级排名的一次过程模拟。

老实说,这个题解感觉不是那么好理解,或许是自己真的太笨了吧~

另一个题解

select a.Score asScore,

(select count(distinct b.Score) from Scores b where b.Score >= a.Score) asRankfromScores aorder by a.Score DESC

作者:johnbear007

链接:https://leetcode-cn.com/problems/rank-scores/solution/fen-cheng-liang-ge-bu-fen-xie-hui-rong-yi-hen-duo-/

来源:力扣(LeetCode)

个人感觉这个题解好理解多了,非常清晰明了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值