数据蛙MySQL45题(11-18)

11. 查询两门及以上不及格课程的同学的学号,姓名及平均成绩

第一步:锁定表:学生表,成绩表

第二步:查询不及格课程的同学成绩表

SELECT *

FROM `sc`

WHERE `score` < 60

第三步:计数不及格同学不及格课程数量,并筛选出不及格课程超过两门的

SELECT a.`SId`,COUNT(a.`SId`),AVG(a.`score`) AS 平均成绩

FROM(SELECT *

FROM `sc`

WHERE `score` < 60) a

GROUP BY a.`SId`

HAVING COUNT(a.`SId`)>=2

第四步:连表学生表,查询查询两门及以上不及格课程的同学的学号,姓名及平均成绩

SELECT b. `SId`,st.`Sname`,平均成绩

FROM (SELECT a.`SId`,COUNT(a.`SId`),AVG(a.`score`) AS 平均成绩

FROM(SELECT *

FROM `sc`

WHERE `score` < 60) a

GROUP BY a.`SId`

HAVING COUNT(a.`SId`)>=2) b

INNER JOIN `student` st

ON b.`SId`=st.`SId`

或者这样,减少一次子查询

SELECT a.`SId`,st.`Sname`,AVG(a.`score`) AS 平均成绩

FROM(SELECT *

FROM `sc`

WHERE `score` < 60) a

INNER JOIN `student` st

ON a.`SId`=st.`SId`

GROUP BY a.`SId`

HAVING COUNT(a.`SId`)>=2

12.检索01课程分数小于60分,按分数降序排列的学生信息(涉及排序)

第一步:锁定表:成绩表和学生表

第二步:筛选出01课程分数小于60的学生id

SELECT `SId`,`score`

FROM `sc`

WHERE `score`<60 AND `CId`='01'

第三步:连表学生表,并按分数将序排列(加一列成绩)

SELECT st.*,a.`score`

FROM `student` st

INNER JOIN (SELECT `SId`,`score`

FROM `sc`

WHERE `score`<60 AND `CId`='01') a

ON st.`SId`=a.`SId`

ORDER BY a.`score` DESC

13.按平均成绩从高到低显示所有学生的所有课程的成绩及平均成绩(涉及排序)

关键词:所有学生,所有课程的成绩,平均成绩

第一步:锁定表:学生表,成绩表

第二步:查询有成绩学生所有课程平均成绩-建新表

SELECT `SId`,AVG(`score`)

FROM `sc`

GROUP BY `SId`

第三步:连表成绩表

SELECT sc.*,平均分

FROM  (SELECT `SId`,AVG(`score`) AS 平均分

FROM `sc`

GROUP BY `SId`) a

LEFT JOIN `sc` sc

ON a.`SId`=sc.`SId`

ORDER BY 平均分 DESC

第四步:连表学生表,使其包含没有参加考试的学生

SELECT st.`SId`,b.`CId`,b.`score`,平均分

FROM `student` st

LEFT JOIN (SELECT sc.*,平均分

FROM  (SELECT `SId`,AVG(`score`) AS 平均分

FROM `sc`

GROUP BY `SId`) a

LEFT JOIN `sc` sc

ON a.`SId`=sc.`SId`) b

ON st.`SId`=b.`SId`

ORDER BY 平均分 DESC

14. 查询各科成绩最高分,最低分和平均分

以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率

及格为:>=60,中等为【70,80),优良为【80,90),优秀为>=90

要求输出成绩课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排序

第一步:锁定表:成绩表,课程表

第二步:筛选出成绩表中的选课人数

SELECT `CId`,COUNT(`SId`)

FROM `sc`

GROUP BY `CId`

第三步:显示课程ID,选修人数,最高分,最低分,平均分,及格率,中等率,优良率,优秀率

SELECT `CId`,

COUNT(`SId`) AS 选课人数,

MAX(`score`) AS 最高分,

MIN(`score`) AS 最低分,

AVG(`score`) AS 平均分,

SUM(CASE WHEN `score`>=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格率,

SUM(CASE WHEN `score`>=70 AND `score`<80 THEN 1 ELSE 0 END)/COUNT(*) AS 中等率,

SUM(CASE WHEN `score`>=80 AND `score`<90 THEN 1 ELSE 0 END)/COUNT(*) AS 优良率,

SUM(CASE WHEN `score`>=90 THEN 1 ELSE 0 END)/COUNT(*) AS 优秀率

FROM `sc`

GROUP BY `CId`

第四步:排序

SELECT `CId`,

COUNT(`SId`) AS 选课人数,

MAX(`score`) AS 最高分,

MIN(`score`) AS 最低分,

AVG(`score`) AS 平均分,

SUM(CASE WHEN `score`>=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格率,

SUM(CASE WHEN `score`>=70 AND `score`<80 THEN 1 ELSE 0 END)/COUNT(*) AS 中等率,

SUM(CASE WHEN `score`>=80 AND `score`<90 THEN 1 ELSE 0 END)/COUNT(*) AS 优良率,

SUM(CASE WHEN `score`>=90 THEN 1 ELSE 0 END)/COUNT(*) AS 优秀率

FROM `sc`

GROUP BY `CId`

ORDER BY 选课人数 DESC,`CId` ASC;

第五步:还需要显示课程名称,连表课程表

SELECT a.*,c.`Cname`

FROM (SELECT `CId`,

COUNT(`SId`) AS 选课人数,

MAX(`score`) AS 最高分,

MIN(`score`) AS 最低分,

AVG(`score`) AS 平均分,

SUM(CASE WHEN `score`>=60 THEN 1 ELSE 0 END)/COUNT(*) AS 及格率,

SUM(CASE WHEN `score`>=70 AND `score`<80 THEN 1 ELSE 0 END)/COUNT(*) AS 中等率,

SUM(CASE WHEN `score`>=80 AND `score`<90 THEN 1 ELSE 0 END)/COUNT(*) AS 优良率,

SUM(CASE WHEN `score`>=90 THEN 1 ELSE 0 END)/COUNT(*) AS 优秀率

FROM `sc`

GROUP BY `CId`

ORDER BY 选课人数 DESC,`CId` ASC) a

LEFT JOIN `course` c

ON a.`CId`=c.`CId`

15. 按各科成绩进行排序,并显示排名,score重复时也继续排名(有问题)

知识点:row_number(),rank(),dense_rank()

(1)row_number():依次排序,不会出现相同排名

(2)rank():出现相同排名时,跳跃排序

(3)dense_rank():出现相同排名时,连续排序

SELECT *,

row_number() over (GROUP BY `CId` ORDER BY `score` DESC) AS 排名

FROM `sc`;  

15.1 按各科成绩进行排序,并显示排名,score重复时合并名次

SELECT *,

rank() over (PARTITION BY `CId` ORDER BY `score` DESC) AS 排名

FROM `sc`;

16. 查询学生的总成绩,并进行排名,总分重复时排名时保留名次空缺

SELECT *,

rank() over (ORDER BY 总成绩 DESC) AS 排名

FROM (SELECT `SId`,SUM(`score`) AS 总成绩

FROM `sc`

GROUP BY `SId`

) a;

16.1 查询学生的总成绩,并进行排名,总分重复时排名时保留名次空缺

SELECT *,

dense_rank() over (ORDER BY 总成绩 DESC) AS 排名

FROM (SELECT `SId`,SUM(`score`) AS 总成绩

FROM `sc`

GROUP BY `SId`

) a;

17. 统计各科成绩各分数段人数:课程编号,课程名称,[100-85),[85-70),[70-60),[60-0]及所占百分比

第一步:锁定表:成绩表,课程表

第二步:使用case when,按照

SELECT sc.`CId`,

c.`Cname`,

SUM(CASE WHEN `score`>85 THEN 1 ELSE 0 END)/COUNT(*) AS '[100-85)',

SUM(CASE WHEN `score`>70 AND `score`<=85 THEN 1 ELSE 0 END)/COUNT(*) AS '[85-70)',

SUM(CASE WHEN `score`>60 AND `score`<=70 THEN 1 ELSE 0 END)/COUNT(*) AS '[70-60)',

SUM(CASE WHEN `score`<=60 THEN 1 ELSE 0 END)/COUNT(*) AS '[60-0]'

FROM `sc` sc

INNER JOIN `course` c

ON sc.`CId`=c.`CId`

GROUP BY `CId`

第三步:使用concat拼接,输出百分比符号

SELECT sc.`CId`,

c.`Cname`,

CONCAT(SUM(CASE WHEN `score`>85 THEN 1 ELSE 0 END)/COUNT(*)*100,'%') AS '[100-85)',

CONCAT(SUM(CASE WHEN `score`>70 AND `score`<=85 THEN 1 ELSE 0 END)/COUNT(*)*100,'%') AS '[85-70)',

CONCAT(SUM(CASE WHEN `score`>60 AND `score`<=70 THEN 1 ELSE 0 END)/COUNT(*)*100,'%') AS '[70-60)',

CONCAT(SUM(CASE WHEN `score`<=60 THEN 1 ELSE 0 END)/COUNT(*)*100,'%') AS '[60-0]'

FROM `sc` sc

INNER JOIN `course` c

ON sc.`CId`=c.`CId`

GROUP BY `CId`

18. 查询各科成绩前三名的记录(mysql8.0)

第一步:锁定表:成绩表,

第二步:排名

SELECT *

dense_rank() over (PARTITION BY `CId` ORDER BY `score` DESC) AS score_rank

FROM `sc`

第三步:筛选出前三名

SELECT *

FROM(SELECT *

dense_rank() over (PARTITION BY `CId` ORDER BY `score` DESC) AS score_rank

FROM `sc`) a

WHERE score_rank <=3

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容