学习数据库后,刷了很多题,在这里记录一些有意思的题。
一、求班里第一高的分数
编写一个 SQL 查询,获取 StudentGrade 表中第一高的分数(Grade)。SQL查询应该返回99作为第一高的分数。如果不存在第一高的分数,那么查询应返回 null。
+----+------+ +---------------------+
| Id | Grade| | HighestGrade |
+----+------+ +---------------------+
|9801| 99 | | 99 |
|9802| 98 | +---------------------+
|9803| 90 | 输出结果
+----+------+
SELECT DISTINCT MAX(Grade) HighestGrade
FROM StudentGrade
二、求班里第二高的分数
编写一个 SQL 查询,获取 StudentGrade 表中第二高的分数(Grade)。SQL查询应该返回98 作为第二高的分数。如果不存在第二高的分数,那么查询应返回 null。
+----+------+ +---------------------+
| Id | Grade| | SecondHighestGrade |
+----+------+ +---------------------+
|9801| 99 | | 98 |
|9802| 98 | +---------------------+
|9803| 90 | 输出结果
+----+------+
解题思路:第二高的分数可以理解为不是最大数的最大数,落实到命令中可以通过子查询去掉第一大的分数,子查询求出最大的分数,再通过"!="去掉第一大的分数,父查询求出第二大的分数。考虑有多个第一大的分数,所以要用distinct去重就不用管几个第一,几个第二之类的。
- 子连接方法
SELECT DISTINCT MAX(Grade) SecondHighestGrade
FROM StudentGrade
WHERE Grade!=(SELECT MAX(Grade) FROM StudentGrade)
引入IFNULL(x,y),若x不为空则返回x,否则返回y,这道题y=null;LIMIT x,y,找到对应的记录就停止
- 使用 IFNULL 和 LIMIT 子句
SELECT IFNULL(
(SELECT DISTINCT Grade
FROM StudentGrade
ORDER BY Grade desc --根据分数倒序
LIMIT 1 OFFSET 1), null) AS SecondHighestGrade
Limit子句
Limit子句可以被用于强制 SELECT 语句返回指定的记录数。Limit接受一个或两个数字参数,参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。
三、求班里第N高的分数
编写一个 SQL 查询,获取 StudentGrade 表中第N高的分数(Grade)。若N=2,SQL查询应该返回98 作为第二高的分数。如果不存在第N高的分数,那么查询应返回 null。
+----+------+ +---------------------+
| Id | Grade| |SecondHighestGrade(2)|
+----+------+ +---------------------+
|9801| 99 | | 98 |
|9802| 98 | +---------------------+
|9803| 90 | 输出结果
|9804| 97 |
+----+------+
解题思路:子查询做题,两表自连接,连接条件设定为表StudentGrade A的Grade小于表StudentGrade B的Grade,以表A的Grade分组,统计表A中每个Grade分组后对应表B中Grade唯一值个数(去重),限定having 计数个数为N-1,即实现了该分组中表A的Grade排名为第N个。
为什么连接用left join?
考虑N=1的特殊情形(计数要求为N-1=0),此时不存在满足条件的记录数,但仍需返回结果。
CREATE FUNCTION getNthHighestGrade(N INT) RETURNS INT
BEGIN
RETURN (
SELECT DISTINCT A.Grade
FROM StudentGrade A LEFT JOIN StudentGrade B ON A.Grade < B.Grade
GROUP BY A.Grade
HAVING count(DISTINCT B.Grade) = N-1
);
END
有什么不足之处欢迎大家评论指出,一起学习。