第31题:查询1990年出生的学生名单
SELECT * FROM student
WHERE YEAR(s_birth)="1990";
第32题: 查询平均成绩大于等于85的所有学生的学号,姓名,和平均成绩
SELECT s.s_id 学号, stu.s_name 姓名, AVG(s_score) 平均成绩
FROM score s JOIN student stu ON s.s_id = stu.s_id
GROUP BY s.s_id
HAVING AVG(s_score)>=85 ;
第33题: 查询每门课的平均成绩,结果按平均成绩升序排序,平均成绩相同时,按课程号降序排列
SELECT AVG(s_score)平均成绩,c_id 课程号
FROM score
GROUP BY c_id
ORDER BY AVG(s_score)ASC, c_id DESC;
第34题;查询课程名为数学,且分数低于60的学生姓名和分数
FROM score s JOIN student stu ON s.s_id = stu.s_id
JOIN course c ON c.c_id = s.c_id
WHERE c_name="数学" AND s_score<60;
第35题: 查询所有学生的课程及分数情况(要求是五列 第一列学生的学号,第二列姓名,第三列语文成绩,第四列数学成绩,第五列英语成绩)
SELECT stu.s_id ,stu.s_name
,MAX(CASE WHEN c.c_name = "语文" THEN s.s_score ELSE NULL END) 语文成绩
,MAX(CASE WHEN c.c_name = "数学" THEN s.s_score ELSE NULL END) 数学成绩
,MAX(CASE WHEN c.c_name = "英语" THEN s.s_score ELSE NULL END) 英语成绩
FROM score s
INNER JOIN course c ON s.c_id=c.c_id
INNER JOIN student stu ON s.s_id=stu.s_id
GROUP BY s.`s_id`;
group by 与case when 联合使用时,
case when 会对非聚合字段的值进行比对,当不适用聚合函数时,只会返回非聚合字段的第一行
数据,所以使用一个聚合函数把真实值搞出
额,不知道怎么解释了,后面再研究
第36题: 查询课程成绩在70分以上课程名称,分数和学生姓名
SELECT c_name 课程名,s_score 分数,c_name 姓名
FROM score s JOIN course c ON s.`c_id`=c.`c_id`
JOIN student stu ON s.`s_id`=stu.`s_id`
WHERE s.`s_score`>70;
第37题: 查询不及格的课程病案课程号从大到小排列
SELECT s.s_id,s_name,s.c_id,c_name,s_score FROM score s
JOIN course c ON c.`c_id`=s.`c_id`
JOIN student stu ON s.`s_id`=stu.s_id
WHERE s.`s_score`<60
ORDER BY c.`c_id` DESC;
第38题 :查询课程编号为03且课程成绩在80分以上的学生的学号和姓名
SELECT s.`s_id` 学号, s_name 姓名 FROM score s
JOIN student stu ON s.`s_id`=stu.`s_id`
WHERE s.`c_id`="03" AND s.`s_score`>80 ;
第39题:求每门课的学生人数(略)
第40题:查询选修“张三”老师所教课程的学生中成绩最高的学生姓名及其成绩
解法一:使用子查询的方式
SELECT stu.s_name 学生姓名,s.s_score 最高分
FROM score s JOIN student stu
ON s.`s_id`=stu.`s_id`
WHERE s.`s_score` =
(SELECT MAX(s_score)
FROM score
GROUP BY c_id
HAVING c_id = (SELECT c_id FROM course WHERE t_id=(SELECT t_id FROM teacher WHERE t_name="张三")))
解法二:使用rank()over()窗口函数的方式来做
关于窗口函数的介绍可以看我另一篇文章的介绍:https://www.jianshu.com/p/6fd853281580
SELECT * FROM
(SELECT stu.s_name 学生姓名,s.`s_score` 分数,rank()over(ORDER BY s.s_score DESC) 排名
FROM score s JOIN student stu
ON s.`s_id`=stu.`s_id`
WHERE c_id = (SELECT c_id FROM course WHERE t_id=(SELECT t_id FROM teacher WHERE t_name="张三")))a
WHERE 排名 = 1
当时我在写第二种写法的时候犯了以下错误:
没有把产生排序的表当成一个新表直接使用了 where 排名= 1,导致报错:Unknown column '排名' in 'where clause'
当需要对窗口函数产生的排名再进行条件筛选时,需要将排序后的表另存为一张表后再在此表的基础上进行筛选,即需要再嵌套一层select.
第二种解法的错误sql如下
SELECT stu.s_name 学生姓名,s.`s_score` 分数,rank()over(ORDER BY s.s_score DESC) 排名
FROM score s JOIN student stu
ON s.`s_id`=stu.`s_id`
WHERE c_id = (SELECT c_id FROM course WHERE t_id=(SELECT t_id FROM teacher WHERE t_name="张三")) AND 排名 = 1
下面是老师的写法:但是我觉得这种写法是不严谨的,因为有可能有多位同学的分数一样且都是最高分,这样的话 使用limit 就会漏掉很多同学,因为他只取了第一行数据,有可能第二行数据的同学也是最高分。
SELECT s.s_id,stu.s_name,s.s_score,c.c_id,c.c_name
FROM score AS s
JOIN course AS c ON s.`c_id`=c.c_id
JOIN teacher AS t ON c.t_id=t.t_id
JOIN student AS stu ON s.`s_id`=stu.`s_id`
WHERE t.t_name= '张三'
ORDER BY s.`s_score` DESC
LIMIT 0,1;