SQL复习练习二(1-15)

1、查询“001”课程比“002”课程成绩高的所有学生的学号;
1查出001的成绩表A,2再查出002的成绩B,3关联AB,查出A表中成绩大于B表的S#。


select A.S# from
(select S#,score from SC
where Sc.C#=001) A
left join
(select S#,score from SC
where Sc.C#=002) B
on A.S#=B.S#


2、查询平均成绩大于60分的同学的学号和平均成绩;
一 用having //这里出错,我直接写avgscore>60,应该写成avg(SC.score)>60
  select S#,avg(score) from sc group by S# having avg(score) >60;
二 用嵌套
select * from (select S#,AVG(score)as avgscore from SC group by S#) a
where a.avgscore>60

3、查询所有同学的学号、姓名、选课数、总成绩;
表:student,CS

select Student.S#,Sname,count(SC.S#),sum(SC.score) from Student left join SC
on Student.S#=Sc.S#
group by Student.S#,Sname
--group by Student.S#,Sname,SC.S#,SC.score PS:聚集函数默认group by了,后面可以不写


4、查询姓“李”的老师的个数;

select count(T#)
from Teacher
where Tname like '李%'
PS 这种情况是索引是有效的,但%李,则索引无效。

5、查询没学过“叶平”老师课的同学的学号、姓名;
一 in/not in
1联接查找学过“叶平”课的学生id,2你懂的
select S#,Sname from
Student
where S# not in
(
select S# from SC
left join Course
on SC.C#=Course.C#
left join Teacher
on Course.T#=Teacher.T#
where Teacher.Tname = '叶平'
)
二 exists

select S#,Sname from
Student A
where not exists (
select S# from SC
left join Course
on SC.C#=Course.C#
left join Teacher
on Course.T#=Teacher.T#
where Teacher.Tname = '叶平'
and A.S#=SC.S#
)

in类查询可以改写为exists类查询
exists类查询性能比in高(原理不明,拿来主义)。

6、查询学过“001”并且也学过编号“002”课程的同学的学号、姓名;
自身连接

select S.S#,S.Sname
from Student S
left join SC A on A.S#=S.S#
left join SC B on B.S#=S.S#
where
A.C#=1
and B.C#=2

子查询 001的表,002表,不为空
这里复习一个join的区别
select A.S# from
(select S# from SC
where Sc.C#=001) A
left join
(select S# from SC
where Sc.C#=002) B
on A.S#=B.S#
where B.S# is not null
等价
select A.S# from
(select S# from SC
where Sc.C#=001) A
inner join
(select S# from SC
where Sc.C#=002) B
on A.S#=B.S#

 

好了,继续

select S#,Sname
from Student S
where S# in(
select A.S# from
(select S# from SC
where Sc.C#=001) A
inner join
(select S# from SC
where Sc.C#=002) B
on A.S#=B.S#
)

也可以转为exists,自已试试

select S#,Sname
from Student S
where exists(

select A.S# from
(select S# from SC
where Sc.C#=001) A
inner join
(select S# from SC
where Sc.C#=002) B
on A.S#=B.S#
where S.S#=A.S#
)

这是文档里的答案
from Student,SC
where Student.S#=SC.S#
相当于一个内连接

select Student.S#,Student.Sname
from Student,SC
where Student.S#=SC.S# and SC.C#='001'
and exists( Select * from SC as SC_2 where SC_2.S#=SC.S# and SC_2.C#='002');

7、查询学过“叶平”老师所教的所有课的同学的学号、姓名;
1查询叶平老师所教的课程总数a
select count(Course.C#)
from Teacher,Course
where Course.T#=Teacher.T#
and Teacher.Tname='叶平'
写多了连接,换这种写法
2每个学生学“叶平”老师的总数b

Select SC.S#,count(Course.T#)
from SC,Course,Teacher
where SC.C#=Course.C#
and Course.T#=Teacher.T#
and Teacher.Tname='叶平'
group by SC.S#

3以a=b作为条件查询

select S#,Sname
from Student
where S# in
(select S# from
(
Select SC.S#,count(Course.T#) as Ccount
from SC,Course,Teacher
where SC.C#=Course.C#
and Course.T#=Teacher.T#
and Teacher.Tname='叶平'
group by SC.S#
)A
where A.Ccount=(select count(Course.C#)
from Teacher,Course
where Course.T#=Teacher.T#
and Teacher.Tname='叶平')
)
这么写有点太难看了……


这是文档答案,他是用having筛选的。

select S#,Sname  
from Student  
where S# in
(select S# from SC ,Course ,Teacher
where SC.C#=Course.C#
and Teacher.T#=Course.T#
and Teacher.Tname='叶平'
group by S#
having count(SC.C#)=
(select count(C#) from
Course,Teacher  where Teacher.T#=Course.T# and Tname='叶平'
)
);

 


8、查询课程编号“002”的成绩比课程编号“001”课程低的所有同学的学号、姓名;
1子查询连接。这里不多说了,可以分别查002,001的成绩表A,B,再连接这两个结果A.S#=B.S# and A.score<B.score,查出S#,再用In 或exists.

9、查询所有课程成绩小于60分的同学的学号、姓名;
1 反向思考,先找取有成绩大于60分学生的ID
select distinct(S#)
from SC
where SC.score>60
再NOT IN
select S#,Sname
from Student
where S# not in(
select distinct(S#)
from SC
where SC.score>60
)

2直接查,不存在 (not existx)成绩大于60分的成绩。其实就是exists
select S#,Sname
from Student
where not exists(
select distinct(S#)
from SC
where SC.score>60
and Student.S#=SC.S#
)

 

10、查询没有学全所有课的同学的学号、姓名;
1查询所有课的总数a,2再查学生学的总数b,3以a=b 或having筛选。参考第7题

11、查询至少有一门课与学号为“001”的同学所学相同的同学的学号和姓名;
从语意上分析,至少有一门课 exists

1查询学号为“1001”的同学所学的课程的C#列表a。
select C# from SC
where SC.S#='001'

2有学过这些课一门的学生学号
select distinct(S#) from SC
where SC.C# in(
select C# from SC
where SC.S#='001'
)
3
select S#,Sname
from Student S
where S# in(
select distinct(S#) from SC
where SC.C# in(
select C# from SC
where SC.S#='001'
))

以 exits查询
select S#,Sname
from Student S
where exists
(
select S# from SC
where SC.C# in(
select C# from SC
where SC.S#='001'
)
and S.S#=SC.S#
)


select Distinct(SC.S#),Sname from Student,SC
where Student.S#=SC.S#
and C# in (select C# from SC where S#='001')

 

文档给的答案是错的!

12、查询至少学过学号为“001”同学所有一门课的其他同学学号和姓名;

这题目有点问题,应该001学过的他都学过。也就是不存在001学过,他没有学过。

1 001同学所学的课程
select C# from SC
where S#=001;
得到总数a
2用in 查询其他学生学的这些课程并得到总数b。

3a<b.

select S#
from SC
where C# in(
select C# from SC
where S#=001
)
group by S#
having count(S#)>=(select count(C#) from SC
where S#=001)

 


12把“SC”表中“叶平”老师教的课的成绩都更改为此课程的平均成绩;
1update SC set score=
(select avg(SC_2.score)
from SC SC_2  
where SC_2.C#=SC.C#
)

2叶平老师教的课(这里有个小问题,如果有主键,直接返回主键,可这表没主键,只好反回两个再说)
where SC.C# in
(
select C# from Course,Teacher
where Course.T#=Teacher.T#
and Teacher.Tname='叶平'
)
结果为
这样出错
update SC set score=
(select avg(SC_2.score)
from SC SC_2  
where SC_2.C#=SC.C#
)

where SC.C# in
(
select C# from Course,Teacher
where Course.T#=Teacher.T#
and Teacher.Tname='叶平'
)

文档的答案如下,但也是错的
update SC set score=(select avg(SC_2.score)
from SC SC_2
where SC_2.C#=SC.C# ) from Course,Teacher where Course.C#=SC.C# and Course.T#=Teacher.T# and Teacher.Tname='叶平');


正确答案是,MSSQL上面的报错,下面的可以,SC不通用SC_2表示?求解答。

update SC
set score=
(select avg(score)
from SC
where C#=SC.C#
)
where C# in
(
select C# from Course,Teacher
where Course.T#=Teacher.T#
and Teacher.Tname='叶平'
)

14、查询和“002”号的同学学习的课程完全相同的其他同学学号和姓名;
同12题,那个是< 这个是=
文档答案
select S# from SC where C# in (select C# from SC where S#='1002')     group by
S# having count(*)=(select count(*) from SC where S#='1002');

15、删除学习“叶平”老师课的SC表记录;
这里有注意的地方,其实开发从没碰上过这种,
一般是查到要删除的ID,再用in。我都是写delete from table where id in()
没有在这里写from的

文档答案是
delete SC    
from course ,Teacher     
where Course.C#=SC.C# and Course.T#= Teacher.T# and Tname='叶平';

我之前的思路。
Delete from SC
where SC.C# in(
select C# from Course,Teacher
where Course.T#=Teacher.T# and Tname='叶平'
)

 

posted @ 2013-06-15 15:22  cclient  阅读(342)  评论(0编辑  收藏  举报