写在前面:
????记录一下解 sql 题的心路历程,题目来自牛客网 sql 专栏,按通过率由高到低刷起,题解来自评论区提供的思路,每 10 道题记录一篇博客,有问题的地方欢迎讨论。
一、分页查询employees表,每5行一页,返回第2页的数据——limit语句
原题目地址:分页查询employees表,每5行一页,返回第2页的数据
????语句 limit,第一个参数为开始记录数(从0开始),第二个参数是记录的条数,此题实际上是从第5条到第9条。
SELECT * FROM employees
limit 5,5;
二、 将titles_test表名修改为titles_2017——rename语句
原题目地址:将titles_test表名修改为titles_2017 ???? 修改表名,属于DDL操作,使用 rename to 语句即可:
alter table titles_test rename to titles_2017;
三、最差是第几名(一)——开窗函数
原题目地址:最差是第几名(一)
????这道题我一开始想到的思路是按 grade 排序,然后当前成绩最差的名次数应该等于上一档次的最差名次+当前成绩人数,但是想不来怎么获得上一档次的最差名次(有点递归那意思😂,而且毕竟这是 sql,没有数组的存储方式),参考了下评论,主要是通过开窗函数。 ????开窗函数格式: 函数名 (列) OVER (选项),OVER 关键字表示把函数当成开窗函数而不是聚合函数。SQL 标准允许将所有聚合函数用做开窗函数,使用 OVER 关键字来区分这两种用法。 比如:
sum (number) over
(order by grade range
between unbounded preceding and current row);
????这里的开窗函数sum (number) over (order by grade range between unbounded preceding and current row) 表示按照 grade 进行排序,然后计算从第一行(UNBOUNDED PRECEDING)到当前行(CURRENT ROW)的和,还可以写作:sum (number) over (order by grade rows between unbounded preceding and current row) (也就是把 range 换成了 rows,前者是比较常见的定位框架)这样的计算结果就是按照 grade 进行排序的人数值的累积和。同理,如果是想要求 当前行前 2 行,到当前行后 2 行的累加和,可以写成:(order by grade rows between 2 preceding and 2 following) ????回到这道题,可以写成简化版的累加:
sum (number) over (order by grade);
????也表示从第一行累加到当前行。 ????整个的 sql 语句为:
select grade,sum(number) over(order by grade) as t_rank
from class_grade
order by grade;
????关于开窗函数,比较详细的介绍可以参考这篇文章:https://www.cnblogs.com/lihaoyang/p/6756956.html
|