暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

SQL脚本案例【7】每个学生,按各科成绩排序,并显示排名

皮皮克克 2024-04-13
174

点击关注公众号,干货第一时间送达


了解过 "开窗" 的小伙伴,

对此题一定不陌生。

属于SQL查询中较为高级的一种语法,

十分好用,

面试的时候,也几乎是必考的。

今天题目的"开窗",要实现"组内排序"功能,

那必然就需要用到:

rank()、dense_rank()、row_number()

排序三剑客!


一,需求场景

请对每个学生,各科成绩进行排序,并显示排名。


结果如下:

不过,诸位仔细想过没有,

如果不同学科,成绩相同,排名怎么计算呢?

例如:

成绩相同,是显示一样的排名,还是不一样的排名呢?

这要看题意。

不过本题并未明确要求,

所以,两种结果都行。

区别在于,你使用的是哪种排序函数。


二,解决方案

【演示工具:Mysql8 + Navicat for Mysql】


(1)使用 rank() 排序函数

select t1.s_id, st.s_name, t1.s_score, t1.rk
from student st
join (
 select 
  s_id,
  s_score,
  rank() over(partition by s_id order by s_score descas rk
 from score
)t1
on st.s_id = t1.s_id


结果集:

相同数据,排名一样。

(2)使用 row_number() 排序函数

select t1.s_id, st.s_name, t1.s_score, t1.rk
from student st
join (
 select 
  s_id,
  s_score,
  row_number() over(partition by s_id order by s_score descas rk
 from score
)t1
on st.s_id = t1.s_id


结果集:

相同数据,排名不一样。

(3)使用 dense_number() 排序函数

(为了体现该函数效果,我们调整一下样本数据)

select t1.s_id, st.s_name, t1.s_score, t1.rk
from student st
join (
 select 
  s_id,
  s_score,
  dense_rank() over(partition by s_id order by s_score descas rk
 from score
)t1
on st.s_id = t1.s_id


结果集:

而如果再用 rank() 查询一次:

select t1.s_id, st.s_name, t1.s_score, t1.rk
from student st
join (
 select 
  s_id,
  s_score,
  rank() over(partition by s_id order by s_score descas rk
 from score
)t1
on st.s_id = t1.s_id


结果集:


懂了吗?

总结:

row_number() 是对组内每行数据依次加一个序号,相同数据,序号也不一样。

rank()、dense_rank() 对组内数据进行排序,添加序号,相同数据,序号一样,

但是 rank() 有排序跳跃,dense_rank() 没有排序跳跃。

(4)over() 函数介绍

over() 函数就是用于"开窗",

其实就是分组,然后对组内数据执行:

xx over() 【注:xx 表示执行函数】

xx 函数操作的。


语法:

xx over(partition by id)

可以理解为:group by id 后,对每个分组内,执行 xx 函数操作。



结束语:
Ok,就是本篇文章的全部内容了。
如果各位有不懂的地方,欢迎发消息给小编,小编会进行详细地解答。
最后,请屏幕前的各位吴彦祖和刘亦菲们,动动你们的小手,给小编一个

文章转载自皮皮克克,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论