题目地址:https://oj.leetcode.com/problems/rank-scores/
这个问题很有趣,写一个类似oracle里的窗口函数rank(),具体描述一下,有一张数据表Scores,里面有两个字段Id和Score,具体结构如下:
+----+-------+
| Id | Score |
+----+-------+
| 1 | 3.50 |
| 2 | 3.65 |
| 3 | 4.00 |
| 4 | 3.85 |
| 5 | 4.00 |
| 6 | 3.65 |
+----+-------+
任务是要写一个sql来给Score字段打一个rank标识,条件是按照Score从大到小排序,相等情况时rank相同,且rank之间没有“洞”,即rank字段是连续值。显然这个任务比rank窗口函数容易一些,但是也是一个棘手的问题。
题目具体给出了输出示例:
+-------+------+
| Score | Rank |
+-------+------+
| 4.00 | 1 |
| 4.00 | 1 |
| 3.85 | 2 |
| 3.65 | 3 |
| 3.65 | 3 |
| 3.50 | 4 |
+-------+------+
平常说实话rank函数或者row_number函数用多了,很少考虑实现,面对这个问题,硬着头皮用笛卡尔积的join解决了,若是在hive中,strict模式可能拒绝笛卡尔积的join,这时还是求助于窗口函数rank吧~~
实现代码如下:
select
o1.Score
,count(o2.Score) as Rank
from(
select * from Scores
)o1
left outer join(
select distinct Score from Scores
)o2
on(o1.Score<=o2.Score)
group by
o1.Id
order by o1.Score desc