前言
最近感觉事情有一些多,所以sql停了几天,但是没有关西,今天我们继续来做sql
第二十二问
题目:使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计各分数段人数,课程ID和课程名称。
分析:这道题和我们之前做过的题目相似。课程号和课程ID本来就是列名,但是分数段人数分散在行中,所以我们要进行行转列的操作,使用函数case when
。
- 课程ID c_id
- 课程名 c_name
- 各分数段人数 sum()
SELECT score.c_id,course.c_name,
SUM(CASE WHEN score.s_score<60 THEN 1 ELSE 0 END)'不及格',
SUM(CASE WHEN score.s_score>=60 AND score.s_score<70 THEN 1 ELSE 0 END) '(60,70)人数',
SUM(CASE WHEN score.s_score>=70 AND score.s_score<85 THEN 1 ELSE 0 END) '(70,85)人数',
SUM(CASE WHEN score.s_score>=85 AND score.s_score<=100 THEN 1 ELSE 0 END) '(85,100)人数'
FROM score
JOIN course
ON score.c_id = course.c_id
GROUP BY score.c_id,course.c_name
第二十三问
题目:查询学生的学号、姓名、平均成绩及其名次
分析:这道题比较简单,我们采用ROW_NUMBER
方法获取排名即可。
- 学号 s_id
- 姓名 s_name
- 平均成绩 AVG(s_score)
- 名次 ROW_NUMBER
SELECT score.s_id '学号',Student.s_name '姓名',AVG(score.s_score) '平均成绩',ROW_NUMBER() OVER(ORDER BY AVG(score.s_score) DESC) '名次'
FROM score
JOIN Student
ON score.s_id = Student.s_id
GROUP BY score.s_id
第二十四问
题目:查询各科成绩前三的记录
分析:按照不同科目进行排名,我们之前学习了partition by
,这里就派的上用处了。由于分组排名之后还是在行里面,所以我们还需要使用when case
将行转列。
- 课程号c_id
- 课程名c_name
- 分组排名ROW_NUMBER() VOER (PARTITION BY c_id ORDER BY s_score)
SELECT s1.c_id '课程号',course.c_name '课程名',
MAX(CASE WHEN s1.rows = 1 THEN s_score ELSE null END) '第一名',
MAX(CASE WHEN s1.rows = 2 THEN s_score ELSE null END) '第二名',
MAX(CASE WHEN s1.rows = 3 THEN s_score ELSE null END) '第三名'
FROM
(SELECT score.c_id,score.s_score,
ROW_NUMBER() OVER(PARTITION BY score.c_id ORDER BY score.s_score DESC) 'rows'
FROM score) s1
JOIN course
on s1.c_id = course.c_id
WHERE s1.rows in (1,2,3)
GROUP BY s1.c_id