数据分析 | MySQL45道练习题(10~18)

题目总览

10.查询没学过[张三]老师讲授的任一门课程的学生姓名

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

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

13.按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩1

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

15.按各科成绩进行排名,并显示排名,score重复时继续排序

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

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

18.查询各科成绩前三名的记录

10.查询没学过[张三]老师讲授的任一门课程的学生姓名

-- 1.先查询出选修了张三老师讲授课程的sid -- 
SELECT s.sid
FROM  teacher t
LEFT JOIN course c
ON t.tid = c.tid
LEFT JOIN sc
ON c.cid = sc.cid
LEFT JOIN student s
ON sc.sid = s.sid
WHERE tname = "张三";
-- 2.与学生表student关联,筛选出不在以上结果内的sid --
SELECT s.*
FROM student s
WHERE sid NOT IN (SELECT s.sid
				  FROM  teacher t
				  LEFT JOIN course c
				  ON t.tid = c.tid
				  LEFT JOIN sc
				  ON c.cid = sc.cid
				  LEFT JOIN student s
				  ON sc.sid = s.sid
				  WHERE tname = "张三");

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

select a.sid,b.sname,avg(a.score) as avg_score
from sc a
left join student b
on a.sid = b.sid
where a.score < 60
group by a.sid
having count(a.cid) >= 2;

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

-- 筛选出01课程分数小于60分的学生id和分数 --
select sid,score
from sc
where score < 60 and cid = '01';

-- 与student表关联,筛选出学生信息 --
select b.*,a.score
from (select sid,score
from sc
where score < 60 and cid = '01') a
left join student b
on a.sid = b.sid
order by score desc;

13.按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

-- 1.先从成绩表中筛选出sid和平均成绩 -- 
SELECT sid,AVG(score) avg_score
FROM sc
GROUP BY sid;

-- 2.再用成绩表sc与以上结果进行关联,筛选出sc的所有信息和avg_score --
SELECT sc.*,a.avg_score
FROM sc
LEFT JOIN(SELECT sid,AVG(score) avg_score
          FROM sc
          GROUP BY sid) a
ON sc.sid = a.sid;

-- 3.用以上结果与学生表student进行关联 --
SELECT a.sid,a.score,a.avg_score,s.sname
FROM (SELECT sc.*,a.avg_score
      FROM sc
      LEFT JOIN(SELECT sid,AVG(score) avg_score
                FROM sc
                GROUP BY sid) a
      ON sc.sid = a.sid) a
LEFT JOIN student s
ON a.sid = s.sid
ORDER BY avg_score DESC;

14.查询各科成绩最高分、最低分和平均分
【分析】以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,
优良率,优秀率 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列

SELECT MIN(score) min_score
			,MAX(score) max_score
			,AVG(score) avg_score
			,COUNT(1) stu_number
			,SUM(CASE WHEN score >= 60 THEN 1 ELSE 0 END)/COUNT(1) 及格率
			,SUM(CASE WHEN score >= 70 AND score < 80 THEN 1 ELSE 0 END)/COUNT(1) 中等率
			,SUM(CASE WHEN score >= 80 AND score < 90 THEN 1 ELSE 0 END)/COUNT(1) 优良率
			,SUM(CASE WHEN score >= 90 THEN 1 ELSE 0 END)/COUNT(1) 优秀率
FROM sc
LEFT JOIN course c
ON sc.cid = c.cid 
GROUP BY sc.cid
ORDER BY stu_number DESC ,sc.cid ASC;

15.按各科成绩进行排名,并显示排名,score重复时继续排序

【分析】变量的使用

SELECT sid,
	   cid,
	   score,
	   @rank:=@rank+1 as rk
FROM sc,(SELECT @rank:=0) as t
ORDER BY score DESC;


-- 自定义变量 --
# ① 定义变量 set @a:=2 (@用来标识变量),使用变量select @a
# ② 定义并使用变量 select @b:=4 
# 修改或者重新赋值 select @b:=6

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

# 法一 
SELECT sid,cid,score,
	   CASE WHEN @sco=score THEN @rank
       ELSE @rank:=@rank+1 END rk,
       @sco:=score
FROM sc,(select @rank:=0,@sco:=null) t
ORDER BY score DESC;

# 法二
SELECT sid,cid,score,
	   CASE WHEN @sco=score THEN @rank
            when  @sco:=score THEN @rank:=@rank+1 
       END rk
FROM sc,(select @rank:=0,@sco:=null) t
ORDER BY score DESC;

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

-- 1、学生的总成绩 --
SELECT sid,SUM(score) sum_score
FROM sc
GROUP BY sid
ORDER BY sum_score DESC;


-- 2、名次排序 --
SELECT a.*,
		@rank:=IF(@sco=sum_score,' ',@rank+1) rk
FROM (SELECT sid,
			 SUM(score) sum_score
	  FROM sc
	  GROUP BY sid
	  ORDER BY sum_score DESC) a,(select @sco:=null,@rank:=0) b

17.统计各科成绩分数段人数,课程编号,课程名称,[100-85][85-70][70-60][60-0]及所占百分比
【分析】分组统计数据,判断各分数段的人数情况。

SELECT sc.cid 课程编号,c.cname 课程名称,COUNT(1) 选修人数
	   ,CONCAT(ROUND(SUM(CASE WHEN sc.score >=0 AND sc.score <= 60 THEN 1 ELSE 0 END)/COUNT(1),2),'%') AS '(0-60]'
       ,CONCAT(ROUND(SUM(CASE WHEN sc.score >=60 AND sc.score <= 70 THEN 1 ELSE 0 END)/COUNT(1),2),'%') AS '(60-70]'
       ,CONCAT(ROUND(SUM(CASE WHEN sc.score >= 70 AND sc.score <= 85 THEN 1 ELSE 0 END)/COUNT(1),2),'%') AS '(70-85]'
       ,CONCAT(ROUND(SUM(CASE WHEN sc.score >= 85 AND sc.score <= 100 THEN 1 ELSE 0 END)/COUNT(1),2),'%') AS '(85-100]'
FROM sc
LEFT JOIN course c
ON sc.cid = c.cid
GROUP BY sc.cid;

-- concat的作用是将两个字符拼接起来 --

18.查询各科成绩前三名的记录

【分析】前三名转化为若大于此成绩的数量少于3即为前三名 

SELECT a.*,c.cname
FROM sc a
LEFT JOIN course c
ON a.cid = c.cid 
WHERE (SELECT COUNT(1) 
	   FROM sc b
       WHERE b.cid = a.cid AND b.score > a.score) < 3
ORDER BY cid DESC,score DESC;

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩的 SQL 语句可能长这样: ``` SELECT student_id, name, AVG(grade) FROM students JOIN grades ON students.id = grades.student_id WHERE grade < 60 GROUP BY student_id HAVING COUNT(*) >= 2 ``` 此语句首先从 students 表和 grades 表中连接数据,然后选择成绩小于 60 的数据,按学生学号分组,并筛选出不及格课程数量大于等于 2 的学生,最后选择学号、姓名和平均成绩输出。 ### 回答2: 首先,需要从学生表和成绩表中检索出查询所需的信息。我们可以在学生成绩表中查询所有成绩于60分的课程,然后再与学生表连接,找出这些学生的姓名和平均成绩。以下是具体步骤: 1. 从成绩表中查询所有不及格课程成绩<60分)的学生学号和课程编号: ``` SELECT student_id, course_id FROM score WHERE score < 60; ``` 2. 利用以上结果作为子查询,在学生表中找出这些学生的姓名和学号: ``` SELECT student.id AS '学号', student.name AS '姓名', AVG(score.score) AS '平均成绩' FROM student JOIN ( SELECT student_id, course_id, score FROM score WHERE score < 60 ) AS score ON student.id = score.student_id GROUP BY student.id HAVING COUNT(DISTINCT score.course_id) >= 2; ``` 3. 上述查询将返回至少有两门不及格课程学生的学号、姓名和平均成绩。注意,我们使用了HAVING子句来筛选掉只有一门不及格课程学生。 希望这个回答对你有所帮助! ### 回答3: 首先,需要明确的是什么是不及格课程。通常来说,不及格的课程指的是成绩在60分以下的课程。 查询这些同学的学号、姓名和平均成绩,需要做如下的步骤: 1. 找到选修课程成绩单。这份成绩单应该包括每位学生在每个课程中的成绩。按照学号排序,并选出成绩小于60分的课程。 2. 找到学生信息表。这份表格应该包括每位学生的学号和姓名。 3. 将成绩单和学生信息表关联起来。可以使用Excel等工具,根据学号将这两份表格合并起来。 4. 计算每位学生平均成绩。将每位学生所选的课程成绩相加,然后除以所选课程数量即可得出平均成绩。 5. 筛选出选了两门及以上不及格课程学生。可以使用Excel等工具,添加筛选条件,或者手动查找这些学生。 经过以上步骤,就可以得出查询结果,包括所有选了两门及以上不及格课程学生的学号、姓名和平均成绩。需要注意的是,为了保护学生隐私,这些信息在公开时需要经过学校和学生本人的同意。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值