数据库综合练习题(教务系统查询)

教务系统中有3个基本表:

学生信息表S(SNO, SNAME, AGE, SEX),其中字段分别表示学号、姓名、年龄、性别。

课程信息表C(CNO, CNAME, CTEACHER),其中字段分别表示课程号、课程名、任课老师。

考试成绩表SC(SNO, CNO, SCGRADE),其中字段分别表示学号、课程号、成绩。

1)把SC表中每门课程的平均成绩插入到另一个已经存在的表SC_C(CNO,CNAME,NUMBER,AVG_GRADE)中,并按平均成绩由高到低进行排序,其中NUMBER表示每门课的选课人数,AVG_GRADE表示每门课程的平均成绩。

insert into sc_c(cno, cname, number, avg_grade)
select sc.cno, c.cname, count(sc.cno), avg(sc.scgrade)
from sc, c where sc.cno=c.cno -- 使用内连接将表sc和表c联结起来 group by sc.cno -- group by 分组之后,聚集函数avg()会计算每个分组的平均值 order by avg(sc.scgrade) desc; -- 进行排序

2)从SC表中把选李士林老师所授课程的女生的选课记录删除

delete from sc 
where sc.cno in (select c.cno from s, c where c.cteacher='李士林' and s.sex='F')  -- 在sc表中确定授课老师是李士林
and sc.sno in (select s.sno from s, c where c.cteacher='李士林' and s.sex='F');  -- 在sc表中确定学生性别是女
-- 在MySQL中,不能在同一个表中即查询又更新,因此在select子查询中不能使用sc表。
-- 将表c和表s组成一个临时的表,在这个临时的表中分别查找满足授课老师是李士林且学生是女性的课程编号和学生编号。要删除的sc表的记录必须同时满足课程编号和学生编号的限制。
-- select * from s, c; 该语句会获得表s和表c的笛卡尔积的返回结果。

3)规定女生所选选李士林老师的课程的成绩都应该在80分以上(含80分)

-- 该功能使用到了SQL的检查约束(即CHECK约束)80分以下的记录无法插入到表中,目前MySQL不支持该约束。

4)找出没有选修过赵士林老师课程的所有学生的姓名

--使用not in子句
select s.sname from s where s.sno not in(
select s.sno from s, c, sc where c.cteacher='赵士林' and c.cno=sc.cno and sc.sno=s.cno);
--使用not exists子句 先对外层表进行loop循环遍历
select s.sname from s where not exists(
select * from c, sc where c.cteacher='赵士林' and c.cno=sc.cno ad sc.sno=s.sno);

5)列出有两门以上(含两门)不及格课程(成绩小于60分)的学生的学号、姓名及其平均成绩

select s.sno, s.sname, avg(sc.scgrade) as avg_grade
from s, sc, (select sno from sc where scgrade<60 group by sno having count(distinct cno)>=2) as bujige
where bujige.sno=s.sno and bujige.sno=sc.sno
group by s.sno;
-- 使用视图
create view bujige as
select sno from sc where scgrade<60 group by sno having count(distinct cno)>=2;
select s.sno, s.sname, avg(sc.scgrade) as avg_grade from s, sc, bujige where bujige.sno=s.sno and bujige.sno=sc.sno group by s,sno;

6)列出既学过高等数学,又学过计算机基础的所有学生的学号、姓名

-- 通过分组并判断组中的数目的方式
select s.sno, s.sname 
from s, (select sno from c, sc where c.cno=sc.cno and c.cname in ('高等数学', '计算机基础') group by sc.sno having count(distinct sc.cno)=2) as a
where s.sno=a.sno;
-- 也可将select子句转变成视图
create view a as
select sno from c, sc where c.cno=sc.cno and c.cname in ('高等数学', '计算机基础') group by sc.sno having count(distinct sc.cno)=2;
select s.sno, s.sname from s, a
where s.sno=a.sno;
-- 通过分别确定选了高等数学和计算机基础的人,然后取交集
select s.sno, s.sname 
from s, 
(select sc.sno from sc, c where c.cname='高等数学' and c.cno=sc.cno) as sc2,
(select sc.sno from sc, c where c.cname='计算机基础' and c.cno=sc.cno) as sc3
where s.sno=sc2.sno and s.sno=sc3.sno;

7)列出线性代数成绩比高等数学成绩高的所有同学的学号、姓名

-- 即选了高等数学又选了线性代数,且线性代数的成绩高于高等数学的成绩
select s.sno, s.sname 
from s,
(select sc.* from sc, c where c.cname='高等数学' and c.cno=sc.cno) as sc2,
(select sc.* from sc, c where c.cname='线性代数' and c.cno=sc.cno) as sc3
where s.sno=sc2.sno and s.sno=sc3.sno and sc2.scgrade<sc3.scgrade;
--使用自连接
select s.sno, s.sname
from s, sc as sc1, c as c1, sc as sc2, c as c2
where (c1.cname='高等数学' and c1.cno=sc1.cno)
and (c2.cname='线性代数' and c2.cno=sc2.cno)
and (sc1.sno=sc2.sno)
and (sc1.scgrade<sc2.scgrade)
and (s.sno=sc1.sno);

8)列出线性代数成绩比高等数学成绩高的所有学生的学号、姓名及其高等数学和线性代数成绩

select s.sno, s.sname, sc1.scgrade as 高等数学成绩,  sc2.scgrade as 线性代数成绩
from s, sc as sc1, sc as sc2, c as c1, c as c2
where (c1.cname='高等数学' and c1.cno=sc1.cno)
and (c2.cname='线性代数' and c2.cno=sc2.cno)
and (sc1.sno=sc2.sno)
and (sc1.scgrade<sc2.scgrade)
and (s.sno=sc1.sno);

 

posted on 2018-10-11 23:23  0820LL  阅读(814)  评论(0编辑  收藏  举报

导航