1 背景
对每门课程 的分数由高到低进行排序
2 步骤
2.1 首先我们看表
sid为学生id,cid为课程id,分数为score
2.2 先对其进行全表排序
SELECT
@rank := @rank + 1 AS row_num ,
a.*
FROM
sc AS a
INNER JOIN ( SELECT @rank := 0 ) AS b ON 1 =1
2.3 分组排序
- 理解了上面的,然后进行 分组,并进行组内排序(要先保证相同的课程号在一起,且分数是由高到低)
SELECT
( @rank := CASE WHEN @cid = a.cid THEN @rank + 1 ELSE 1 END ) AS row_num,
a.sid,
( @cid := a.cid ) AS cid,
a.score
FROM
( SELECT * FROM sc ORDER BY cid, score DESC ) AS a -- 注意,这里我们先对原表进行了排序,保证相同的课程号在一起,且分数是由高到低
INNER JOIN ( SELECT @rank := 0, @cid := 0 ) AS b ON 1 =1
为什么要先进行排序呢?
这涉及到了我们最终目标和sql逻辑的关系:我们最终要的是 对课程进行分组,然后对每门课里的分数排序;而sql语句中,当@cid=cid时,@cid+1 否则就要设置为1,也就是@cid会先判断这个cid是不是和上一个相同,相同的话@cid+1,不同的话就返回1,这样就保证了按课程分组(所以要先将课程号相同的放在一起),且分组后进行排序(将分数按降序排列),最终就解决了我们的问题。
2.4 相同的认为排名相同
set @rank:=0,@num:=0,@numm:=0; -- 初始化
select country,
@num:=population, -- 自定义函数,num为人数
if (@num<>@numm,@rank:=@rank+1,@rank),-- 当num<>numm时,rank+1
@numm:=@num as dd -- 将@num的值赋给@numm
from c_p_copy3
order by population desc
3 其它
低版本的mysql没有窗口函数,因此进行组内排序比较复杂。
如果能够用窗口函数,会特别简单,
注意row_number()over() rank()over() densk_rank()over() 的区别。
参考链接:
https://blog.csdn.net/weixin_41471128/article/details/83997276