目录
- [1 题目](#1 题目)
- [2 建表语句](#2 建表语句)
- [3 题解](#3 题解)
1 题目
有学生成绩表,包含学生姓名、学科、成绩三个字段,请用一条SQL查询出每个学科排名第三名的学生,他的学科成绩、总成绩、以及总排名。
样例数据
+----------+----------+--------+
| student | subject | score |
+----------+----------+--------+
| 张三 | 语文 | 95 |
| 李四 | 语文 | 90 |
| 王五 | 语文 | 88 |
| 赵六 | 语文 | 77 |
| 张三 | 数学 | 80 |
| 李四 | 数学 | 90 |
| 王五 | 数学 | 92 |
| 赵六 | 数学 | 84 |
| 张三 | 英语 | 82 |
| 李四 | 英语 | 93 |
| 王五 | 英语 | 88 |
| 赵六 | 英语 | 68 |
+----------+----------+--------+
2 建表语句
sql
--建表语句
create table if not exists t_student_score_13
(
student string,
subject string,
score bigint
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
STORED AS orc;
--插入数据
insert into t_student_score_13(student, subject, score)
values ('张三', '语文', 95),
('李四', '语文', 90),
('王五', '语文', 88),
('赵六', '语文', 77),
('张三', '数学', 80),
('李四', '数学', 90),
('王五', '数学', 92),
('赵六', '数学', 84),
('张三', '英语', 82),
('李四', '英语', 93),
('王五', '英语', 88),
('赵六', '英语', 68);
3 题解
- 查询学科排名、每个学生总成绩
sql
select student,
subject,
score,
row_number() over (partition by subject order by score desc) as subject_rn,
sum(score) over (partition by student) as total_score
from t_student_score_13
执行结果
+----------+----------+--------+-------------+--------------+
| student | subject | score | subject_rn | total_score |
+----------+----------+--------+-------------+--------------+
| 张三 | 语文 | 95 | 1 | 257 |
| 张三 | 英语 | 82 | 3 | 257 |
| 张三 | 数学 | 80 | 4 | 257 |
| 李四 | 语文 | 90 | 2 | 273 |
| 李四 | 英语 | 93 | 1 | 273 |
| 李四 | 数学 | 90 | 2 | 273 |
| 王五 | 语文 | 88 | 3 | 268 |
| 王五 | 英语 | 88 | 2 | 268 |
| 王五 | 数学 | 92 | 1 | 268 |
| 赵六 | 语文 | 77 | 4 | 229 |
| 赵六 | 英语 | 68 | 4 | 229 |
| 赵六 | 数学 | 84 | 3 | 229 |
+----------+----------+--------+-------------+--------------+
- 根据学生总分计算学生总排名
sql
select student,
subject,
score,
subject_rn,
total_score,
row_number() over (partition by subject order by total_score desc) as total_rn
from (select student,
subject,
score,
row_number() over (partition by subject order by score desc) as subject_rn,
sum(score) over (partition by student) as total_score
from t_student_score_13) t
执行结果
+----------+----------+--------+-------------+--------------+-----------+
| student | subject | score | subject_rn | total_score | total_rn |
+----------+----------+--------+-------------+--------------+-----------+
| 李四 | 数学 | 90 | 2 | 273 | 1 |
| 王五 | 数学 | 92 | 1 | 268 | 2 |
| 张三 | 数学 | 80 | 4 | 257 | 3 |
| 赵六 | 数学 | 84 | 3 | 229 | 4 |
| 李四 | 英语 | 93 | 1 | 273 | 1 |
| 王五 | 英语 | 88 | 2 | 268 | 2 |
| 张三 | 英语 | 82 | 3 | 257 | 3 |
| 赵六 | 英语 | 68 | 4 | 229 | 4 |
| 李四 | 语文 | 90 | 2 | 273 | 1 |
| 王五 | 语文 | 88 | 3 | 268 | 2 |
| 张三 | 语文 | 95 | 1 | 257 | 3 |
| 赵六 | 语文 | 77 | 4 | 229 | 4 |
+----------+----------+--------+-------------+--------------+-----------+
- 查询每个学科的第三名
我们已经把所有需要的字段都查询出来了,只需要限定 subject_rn = 3 得到学科排名第三的同学记录即可。
sql
select student,
subject,
score,
total_score,
total_rn
from (select student,
subject,
score,
subject_rn,
total_score,
row_number() over (partition by subject order by total_score desc) as total_rn
from (select student,
subject,
score,
row_number() over (partition by subject order by score desc) as subject_rn,
sum(score) over (partition by student) as total_score
from t_student_score_13) t) tt
where subject_rn = 3
执行结果
+----------+----------+--------+--------------+-----------+
| student | subject | score | total_score | total_rn |
+----------+----------+--------+--------------+-----------+
| 赵六 | 数学 | 84 | 229 | 4 |
| 张三 | 英语 | 82 | 257 | 3 |
| 王五 | 语文 | 88 | 268 | 2 |
+----------+----------+--------+--------------+-----------+