题目:请你找出每个岗位分数排名前2名的用户,得到的结果先按照language的name升序排序,再按照积分降序排序,最后按照grade的id升序排序

结题思路:先对每个岗位的分数进行排名,然后取排名1、2的结果即可。但需要注意结果表中,JAVA语言出现3个用户,其中有两个分数一致,也就是说,分数一致排名相同且序号要连续,故这里要用dese_rank()排序

总结下3种常用排序窗口函数区别:
  1. row_number 会为查询出来的每一行记录生成一个序号,依次顺序排序且不会重复
  2. rank rank与row_number不同的是,rank函数考虑到over子句中排序字段值相同的情况,over子句中排序字段值相同的序号是一样的后面字段值不相同的序号将跳过相同的排名号排下一个;
  3. dense_rank 的功能与rank函数类似,dense_rank函数在生成序号时是连续的,而rank函数生成的序号有可能不连续。dense_rank函数出现相同排名时,将不跳过相同排名号,值紧接上一次的值。在各个分组内,rank()是跳跃排序,有两个第一名时接下来就是第三名,dense_rank()是连续排序,有两个第一名时仍然跟着第二名。


本题代码如下:
select id,name,score from
(
select g.id,l.name,g.score,
dense_rank() over(partition by l.name order by g.score desc)as rn
from grade as g left join language as l on g.language_id=l.id
)t
where t.rn<=2
order by name,score desc,id