必知必会sql面试题练习总结之学生课程篇



先建表 插入数据(oracle数据库为例,建表没有考虑外键约束)
create table tb_student(
student_id number(11),
s_name varchar2(20),
s_age number(11),
s_sex varchar2(2))


create table tb_course(
course_id number(11),
c_name varchar2(20),
teacher_id number(11)
)


create table tb_score(
student_id number(11),
score varchar2(20),
course_id number(11)
)


create table tb_teacher(
teacher_id number(11),
t_name varchar2(20)
)
将tb_score 字段score的类型改为 number类型 
alter table tb_score rename column score to score_tmp;
alter table tb_score add  score number(11)
update  tb_score set score = trim(score_tmp)
alter table tb_score drop column score_tmp;


开始实战练习
1.查询课程id=1的成绩大于课程id=2的成绩的学生学号
select sc1.student_id
  from tb_score sc1, tb_score sc2
 where sc1.course_id = 1
   and sc2.course_id = 2
   and sc1.score > sc2.score
   and sc1.student_id = sc2.student_id
   
 select * from
 (select student_id ,Score from tb_score  where course_id=1) a,
 (select student_id ,Score from tb_score  where course_id=2) b
 where a.student_id=b.student_id and a.Score> b.score
2.查询平均成绩大于60分的同学的学号和平均成绩;
select student_id 学生学号 ,avg(score) 平均成绩 from  tb_score group by student_id having avg(score)>60 order by avg(score) desc
3.查询所有同学的学号、姓名、选课数、总成绩;
select s.student_id 学生学号,
       s.s_name 学生姓名,
       count(course_id) 选课数,
       sum(score) 总成绩
  from tb_student s, tb_score s1
 where s.student_id = s1.student_id
 group by s.student_id , s.s_name , s.s_age ,s.s_sex order by sum(score) desc
4.查询姓“李”的老师的个数;
select count(distinct teacher_id) from tb_teacher where t_name like '李%'
5.查询没学过“肖老师”老师课的同学的学号、姓名;用 (not) exists 代替 (not) in 
select s.student_id 学生编号, s.s_name 学生姓名
  from tb_student s
 where  exists (select *
          from tb_teacher tt, tb_course tc, tb_score ts
         where s.student_id = ts.student_id
           and ts.course_id = tc.course_id
           and tt.teacher_id = tc.teacher_id
           and tt.t_name = '肖老师')
6.查询学过“1”并且也学过编号“2”课程的同学的学号、姓名;
select s.student_id 学生编号, s.s_name 学生姓名 
 from tb_student s ,tb_score ts
 where s.student_id = ts.student_id and ts.course_id =1 and exists (select *
 from tb_student s ,tb_score ts
 where s.student_id = ts.student_id and ts.course_id =2)
 
 select s.student_id 学生编号, s.s_name 学生姓名 
 from tb_student s ,tb_score ts
 where s.student_id = ts.student_id and ts.course_id =1  
 intersect
 select s.student_id 学生编号, s.s_name 学生姓名 
 from tb_student s ,tb_score ts
 where s.student_id = ts.student_id and ts.course_id =2
PS:EXISTS用于检查子查询是否至少会返回一行数据,该子查询实际上并不返回任何数据,而是返回值True或False。那么,这里我们来看一下in和exists的区别:
①in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。
②一直以来认为exists比in效率高的说法是不准确的。
 -->如果查询的两个表大小相当,那么用in和exists差别不大。
 -->如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in。
(7)查询学过“肖老师”老师所教的所有课的同学的学号、姓名;
 select s.student_id 学生编号, s.s_name 学生姓名 from tb_student s ,tb_score ts ,tb_teacher tt ,tb_course tc
 where s.student_id = ts.student_id and ts.course_id = tc.course_id and tc.teacher_id = tt.teacher_id and tt.t_name = '肖老师'
(8)查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
 select s.student_id 学生编号, s.s_name 学生姓名  from tb_student s, 
 (select student_id ,score from tb_score ts where ts.course_id =1) a ,
 (select student_id ,score from tb_score ts where ts.course_id =2) b 
 where s.student_id = a.student_id and s.student_id = b.student_id and a.score < b.score
9.查询有课程成绩小于60分的同学的学号、姓名;
 select s.student_id 学生编号, s.s_name 学生姓名, min(score) 最低成绩
   from tb_student s, tb_score ts
  where s.student_id = ts.student_id
  group by s.student_id, s.s_name, s.s_age, s.s_sex
 having min(score) < 60
 select s.student_id 学生编号, s.s_name 学生姓名
 from tb_student s
 where s.student_id in
 (
 select distinct(ts.student_id) from tb_score ts where  ts.student_id = s.student_id and ts.score <60
 )
10.查询没有学全所有课的同学的学号、姓名;
select s.student_id 学生编号, s.s_name 学生姓名
  from tb_student s
 where s.student_id not in
       (select ts.student_id
          from tb_score ts
         group by ts.student_id
        having count(distinct ts.course_id) = (select count(distinct
                                                           tc.course_id)
                                                from tb_course tc))
(11)查询至少有一门课与学号为“1001”的同学所学相同的同学的学号和姓名;
select distinct(s.student_id) 学生编号, s.s_name 学生姓名
  from tb_student s ,tb_score ts 
  where s.student_id = ts.student_id and ts.course_id in (
  select distinct(course_id)  from tb_score ts2 where ts2.student_id = 1001
  ) order by s.student_id
(13)把“成绩”表中“温老师”老师教的课的成绩都更改为此课程的平均成绩;
 update tb_score t
    set t.score = (select avg(score)
                   from tb_score ts, tb_course tc, tb_teacher tt
                  where ts.course_id = tc.course_id
                    and tc.teacher_id = tt.teacher_id
                    and tt.t_name = '温老师')
  where t.course_id = (
  select course_id from tb_course tc ,tb_teacher tt where tc.teacher_id = tt.teacher_id and tt.t_name = '温老师')


(14)查询和“1001”号的同学学习的课程完全相同的其他同学学号和姓名;
select distinct (s.student_id) 学生编号, s.s_name 学生姓名
  from tb_student s
 where s.student_id != 1001
   and s.student_id in
       (select distinct (t.student_id)
          from tb_score t
         where t.course_id in (select ts.course_id
                                 from tb_score ts
                                where ts.student_id = 1001)
         group by t.student_id
        having count(course_id) = (select count(course_id)
                                    from tb_score
                                   where student_id = 1001))


(17)按平均成绩从低到高显示所有学生的“语文”、“数学”、“英语”三门的课程成绩,按如下形式显示: 学生ID,语文,数学,英语,有效课程数,有效平均分;
select t.student_id as 学生编号,
       (select score
          from tb_score t1
         where t.student_id = t1.student_id
           and t1.course_id = 1) as 语文,
       (select score
          from tb_score t1
         where t.student_id = t1.student_id
           and t1.course_id = 4) as 数学,
       (select score
          from tb_score t1
         where t.student_id = t1.student_id
           and t1.course_id = 2) as 英语,
       avg(t.score) as 平均成绩,
       count(t.course_id) as 有效科目数
  from tb_score t
 group by t.student_id
 order by avg(t.score) desc









  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值