LeetCode-SQL-three
本文中主要是介绍LeetCode
中关于SQL
的练习题,从易到难,循序渐进。文中会介绍题目和提供尽可能多的解答方案。从本文开始属于$\color{red}{中等}$难度
177-第N高的薪水
题目
编写一个 SQL 查询,获取 Employee
表中第 n 高的薪水(Salary)
例如上述 Employee
表,n = 2 时,应返回第二高的薪水 200
。如果不存在第 n 高的薪水,那么查询应返回 null
答案
limit m,n
相当于是limit n offset m
- 查询薪水,降序排列,同时进行去重
1 | select distinct salary |
- 通过
ifnull
函数判断是否为空值
1 | select ifnull((select distinct salary -- 方法1 |
1 | -- 方法2 |
1 | -- 方法3 |
178-分数排名
题目
编写一个 SQL 查询来实现分数排名。如果两个分数相同,则两个分数排名(Rank)相同。请注意,平分后的下一个名次应该是下一个连续的整数值。换句话说,名次之间不应该有“间隔”
答案
最终的结果包含两个部分:
- 降序排列的分数
- 每个分数对应的排名
第一部分的查询语句为:
1 | select a.Score as score |
第二部分的分析过程:
假设给定了某个分数X
,如何计算它的排名rank
,分为两个步骤:
- 先提取所有的大于等于X分数的集合H
- 将
H
去重后的元素个数就是X
的排名
看个栗子:
99,98,98,97,97,97
,现在想知道97的排名,去重之后的元素排序为99,98,97
,个数为3
,所以97
的排名为3
1 | select b.Score from Scores b where b.Score >= X -- 提取集合X |
1 | select count(distinct b.Score) from Scores b where b.Score >= X as rank; -- 去重后的元素个数作为排名 |
结果中rank对应的是第一部分的分数,所以X就是a.Score,两个部分合在一起为:
1 | select a.Score as Score, |
图解SQL排名
题目
下面的班级表记录了每个学生所在的班级和成绩。
现在需要按成绩来排名,如果两个分数相同,那么排名要是并列的。
正常排名是1,2,3,4,但是现在前3名是并列的名次,排名结果是:1,1,1,2。
解题
如果涉及到排名问题,可以使用$\color{red}{窗口函数}$,3个函数为:
- rank
- dense_rank
- row_number
1 | select *, |
3个函数的具体区别:
MySQL 8开始才支持窗口函数