MySQL经典50题-第11-15题-2

239 阅读2分钟

题目14

题目需求

查询没有修过张三老师讲授的任何一门课程的学生姓名

分析过程

老师:Teacher——>t_name(t_id)

课程:Course——>t_id——>c_id

姓名:Student

SQL实现

自己的方法,具体过程如下:

select s_name   -- 4、学号取反找到学生姓名
from Student 
where s_id not in(
  select distinct(s_id) -- 3、课程号找到对应的学号
  from Score 
  where c_id=(
    select c_id -- 2、教师编号找到对应的课程号
    from Course 
    where t_id=(
      select t_id   -- 1、姓名找到教师编号
      from Teacher 
      where t_name='张三')
  ));
 -- 修过张老师课程的学生的学号
 select distinct(s_id) 
 from Score 
 where c_id=(
   select c_id 
   from Course 
   where t_id=(
     select t_id 
     from Teacher 
     where t_name='张三')); -- 修过张三老师课的学生

题目15

题目需求

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

分析过程

我们需要统计每个学生不及格的课程的数量:通过Score表中的数据直接统计c_id小于等于60的数量;然后再和Student表进行联结

SQL实现

首先看看哪些同学是满足两门或者两门以上是及格的

-- 2门及以上不及格的

select 
 s_id
  ,round(avg(s_score))  avg_score
from Score 
where s_score < 60 -- 小于60分,不及格
group by s_id
having count(s_score) >= 2;   -- 不及格的有2门以上

说明04,06是我们最终想要的结果

-- 自己的方法
select 
 s.s_id
 ,s.s_name 
 ,t.avg_score
from Student s
join (select 
       s_id
       ,round(avg(s_score))  avg_score
      from Score 
      where s_score < 60 
      group by s_id
      having count(s_score) >= 2)t
on s.s_id=t.s_id
-- 参考方法1

select 
 a.s_id,
 a.s_name,
 ROUND(AVG(b.s_score)) 
from Student a 
left join Score b 
on a.s_id = b.s_id
where a.s_id in(
  select s_id 
  from Score 
  where s_score<60 
  group by s_id 
  having count(1)>=2)
group by a.s_id,a.s_name

-- 参考方法2
select 
 s.s_id
 ,s_name
 ,round(avg(s_score), 2) avg_score
from Student s
join Score sc
on s.s_id=sc.s_id
and sc.s_score < 60  -- 不及格
group by s.s_id   -- 学号分组
having count(sc.c_id )>= 2;   -- 2门课 

改进点

上面的两种方法都没有考虑都08学生,3门都没有成绩,这个本题需要改进的地方。