一枚小产品的学习记录
在做sql练习题时了解到的新函数,做个简要的记录,若有不严谨的地方,请指正。
mysql 8.0以上版本才支持窗口函数
以下是个人总结
row_number()over(partition by字段1 order by 字段2) 的结果是每一行记录生成一个序号,依次排序且排序的序号不会重复
rank()over(partition by字段1 order by 字段2) 的结果会考虑排序字段值相同的情况,若排序字段的值相同则其序号是一样的,后续不同字段值的序号为(前一行序号+N,其中N为前一个字段值重复的行数),比如 1 1 3 4 4 4 7。**
dense_rank()over(partition by字段1 order by 字段2) 的结果也会考虑排序字段值相同的情况,即排序字段的值相同那么他们的序号是一样的,但是与rank()****的区别是后续不同字段值的序号为(前一行序号+1),比如 1 1 2 2 3 4 5
另外:over(partition by字段1 order by 字段2)中的partition by 字段1 是可以省略的但是order by 字段2 不可省略
详细演示见下文:
本文内使用到的建表、插入数据sql 可在我写的sql面试50题的第一篇文章内找到.
按各科成绩进行排序,并显示排名
#rank()over()的使用
SELECT s.s_id 学号,s_name 姓名,c_name 课程,s_score 成绩
,rank()over(PARTITION BY s.c_id ORDER BY s_score DESC) 科内排名
FROM student stu
JOIN score s ON stu.s_id = s.s_id
JOIN course c ON s.c_id = c.c_id;
#执行结果如下
#rank()over()的使用,不使用partition by的效果
SELECT s.s_id 学号,s_name 姓名,c_name 课程,s_score 成绩
,rank()over(ORDER BY s_score DESC) 科内排名
FROM student stu
JOIN score s ON stu.s_id = s.s_id
JOIN course c ON s.c_id = c.c_id;
#执行结果如下
#row_number()over()的使用
SELECT s.s_id 学号,s_name 姓名,c_name 课程,s_score 成绩
,row_number()over(PARTITION BY s.c_id ORDER BY s_score DESC) 科内排名
FROM student stu
JOIN score s ON stu.s_id = s.s_id
JOIN course c ON s.c_id = c.c_id;
#执行结果如下
#dense_rank()over()的使用
SELECT s.s_id 学号,s_name 姓名,c_name 课程,s_score 成绩
,dense_rank()over(PARTITION BY s.c_id ORDER BY s_score DESC) 科内排名
FROM student stu
JOIN score s ON stu.s_id = s.s_id
JOIN course c ON s.c_id = c.c_id;
#执行结果如下
#****与group by 共同使用
#对学生总成绩进行从大到小排序
SELECT stu.s_id 学号, stu.s_name 姓名
,SUM(s.s_score) 总成绩,rank () over (ORDER BY SUM(s.s_score) DESC) 排名
FROM student stu
JOIN score s ON stu.s_id = s.s_id
GROUP BY stu.s_id;
#执行结果如下