下图分别是练习中的教师表,学生表,成绩表,科目表
练习如下
1、查询“c001”课程比“c002”课程成绩高的所有学生的学号;
方法一:使用自连接
select c.sno 学号
from sc c
inner join sc t on c.sno=t.sno and c.cno='c001' and t.cno='c002'
where c.score>t.score
方法二:使用相关自查询
select s.sno from sc s
where s.sno in (
select c.sno from sc c
where s.score>c.score and s.cno='c001' and t.cno='c002'
)
2、查询平均成绩大于60 分的同学的学号和平均成绩
select c.sno,avg(score) 平均成绩
from sc c
group by c.sno
having avg(score)>60
3、查询所有同学的学号、姓名、选课数、总成绩;
select t.sno 学号,t.sname 姓名,count(s.cno) 选课数,sum(s.score) 总成绩
from student t
left join sc s on t.sno=s.sno
group by t.sno,t.sname
4、查询姓“刘”的老师的个数;
select count(tname) 数量
from teacher t
where t.tname like '刘%'
5、查询没学过“谌燕”老师课的同学的学号、姓名;
方法一:
5.1查询出老师的编号
select t.tno from teacher t
where t.tname='谌燕'
5.2查询出老师的所有课程
select s.cno
from course s
inner join teacher t on t.tno=s.tno
where t.tname='谌燕'
5.3查询出学过“谌燕”老师课的同学的学号
select c.sno
from sc c
where c.cno in (
select s.cno
from course s
inner join teacher t on t.tno=s.tno
where t.tname='谌燕'
)
group by c.sno
5.4查询出没学过“谌燕”老师课的同学的学号、姓名
select d.sno,d.sname
from student d
where d.sno not in (
select c.sno
from sc c
where c.cno in (
select s.cno
from course s
inner join teacher t on t.tno=s.tno
where t.tname='谌燕'
)
)
方法二:
select d.sno,d.sname
from student d
where d.sno not in (
select distinct s.sno from student s
left join sc c on c.sno=s.sno
left join course o on c.cno=o.cno
left join teacher t on t.tno = o.tno
where t.tname = '谌燕'
)
6、查询学过“c001”并且也学过编号“c002”课程的同学的学号、姓名;
方法一:通过子查询+自连接
---.1查询学过“c001”并且也学过编号“c002”课程的同学的学号
select c.sno
from sc c
inner join sc t on c.sno=t.sno
where (c.cno='c001' and t.cno='c002') or (c.cno='c002' and t.cno='c001')
group by c.sno
---.2、查询学过“c001”并且也学过编号“c002”课程的同学的学号、姓名;
select d.sno,d.sname
from student d
where d.sno in (select c.sno
from sc c
inner join sc t on c.sno=t.sno
where (c.cno='c001' and t.cno='c002') or (c.cno='c002' and t.cno='c001')
group by c.sno)
方法二:通过相关子查询
select t.sno,t.sname from student t
left join sc s on s.sno=t.sno
where s.sno in (
select c.sno from sc c
where s.cno='c001' and c.cno='c002'
)
7、查询学过“谌燕”老师所教的所有课的同学的学号、姓名;
---5.2查询出老师的所有课程的数量
select count(s.cno)
from course s
inner join teacher t on t.tno=s.tno
where t.tname='谌燕'
SELECT DISTINCT student.sno,student.sname
FROM student
WHERE student.sno IN(
SELECT sc.sno
FROM sc
where sc.cno in (
select course.cno
from course
where course.tno in(
select teacher.tno from teacher
where teacher.tname='谌燕'
)
)
group by sc.sno
having count(distinct sc.sno)=(
select count(s.cno)
from course s
inner join teacher t on t.tno=s.tno
where t.tname='谌燕'
)
)
方法二:
select s.sno,s.sname from student s
left join sc c on c.sno=s.sno
where c.cno in(
select o.cno from teacher t
left join course o on t.tno=o.tno
where t.tname='谌燕')
group by s.sno,s.sname
having count(c.cno)=(
select count(o.cno) from teacher t
left join course o on t.tno=o.tno
where t.tname='谌燕'
)
8、查询课程编号“c002”的成绩比课程编号“c001”课程低的所有同学的学号、姓名;
select t.sno 学号,t.sname 姓名
from student t
where t.sno not in (
select c.sno 学号
from sc c
inner join sc t on c.sno=t.sno and c.cno='c001' and t.cno='c002'
where c.score>t.score)
9、查询所有课程成绩小于60 分的同学的学号、姓名;
--方法一,
select s.sno 学号,s.sname 姓名
from student s
full outer join sc t on t.sno=s.sno
group by s.sno,s.sname
having sum(t.score)<60
--方法二
select s.sno 学号,s.sname 姓名
from student s
where s.sno not in(
select c.sno
from sc c
group by c.sno
having sum(c.score)>60
)
10、查询没有学全所有课的同学的学号、姓名;
select s.sno,s.sname
from student s
where s.sno in (
--查询出满足条件的所有sno
select c.sno
from sc c
group by c.sno
having count(c.cno)=(
select count(o.cno) from course o
)
)
11、查询至少有一门课与学号为“s001”的同学所学相同的同学的学号和姓名;
select s.sno,s.sname
from student s
full outer join sc c on s.sno=c.sno
where c.cno in(
select sc.cno from sc
where sc.sno='s001'
) and c.sno not like 's001'
group by s.sno,s.sname
12、查询至少学过学号为“s001”同学所有课的其他同学学号和姓名;
select t.sno,t.sname from student t
inner join sc s on s.sno=t.sno
where s.cno in (
select c.cno from sc c
where c.sno='s002'
) and s.sno not like 's002'
group by t.sno,t.sname
having count(s.cno)>=(
select count(n.cno) from sc n
where n.sno='s002'
)
13、把“SC”表中“谌燕”老师教的课的成绩都更改为此课程的平均成绩;
UPDATE SC
SET SC.score=(
SELECT avg(s.score) from sc s
inner join course o on s.cno=o.cno
inner join teacher t on t.tno=o.tno
where t.tname='谌燕' and sc.cno=s.cno
group by s.cno
)
where sc.cno=(
select c.cno from course c
left join teacher t on t.tno=c.tno
where t.tname='谌燕' and sc.cno=c.cno
)
14、查询和“s001”号的同学学习的课程完全相同的其他同学学号和姓名;
方法一:
select s.sno from sc s
left join (select distinct c.cno from sc c where c.sno='s001') c1 on c1.cno=s.cno
group by s.sno
having count(s.cno)=(select distinct count(c.cno) from sc c where c.sno='s001') and s.sno<>'s002'
15、删除学习“谌燕”老师课的SC 表记录;
16、向SC 表中插入一些记录,这些记录要求符合以下条件:没有上过编号“c002”课程的同学学号、“c002”号课的平均成绩;
INSERT INTO sc
(sno, cno, score)
VALUES ('s005','c001',
(select AVG(s.score)
from sc s
group by s.cno
having s.cno='c002'
))
17、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
select s.cno 课程ID,MAX(s.score) 最高分,min(s.score) 最低分
from sc s
group by s.cno
18、按各科平均成绩从低到高和及格率的百分数从高到低顺序
select s.cno 科目,avg(s.score) 平均成绩,cast(
round(cast(SUM(case when s.score>60 then 1 else 0 end) as float)/cast(count(*) as float)*100,2)
as nvarchar(10) )+'% ' 及格率
from sc s
group by s.cno
order by avg(s.score) asc,cast(
round(cast(SUM(case when s.score>60 then 1 else 0 end) as float)/cast(count(*) as float)*100,2)
as nvarchar(10) ) desc
select s.cno 科目
,
cast(
round(cast(SUM(case when s.score>60 then 1 else 0 end) as float)/cast(count(*) as float)*100,2)
as nvarchar(10) )+'% ' 及格率
from sc s
group by s.cno
19、查询不同老师所教不同课程平均分从高到低显示
select t.tname 教师,c.cno 科目, avg(s.score) 平均值
from sc s
right join course c on s.cno=c.cno
right join teacher t on c.tno=t.tno
group by c.cno,t.tname
order by avg(s.score) desc
-- select *
--from sc s
--full outer join course c on s.cno=c.cno
--full outer join teacher t on c.tno=t.tno
--group by c.cno,t.tname
20、统计列印各科成绩,各分数段人数:课程ID,课程名称,[100-85],[85-70],[70-60],[ <60]
select
c.cno 课程id,
o.cname 课程名称,
sum(case when c.score>85 and c.score<100 then 1 else 0 end) [100-85],
sum(case when c.score>70 and c.score<85 then 1 else 0 end) [85-70],
sum(case when c.score>60 and c.score<70 then 1 else 0 end) [70-60],
sum(case when c.score<60 then 1 else 0 end) [ <60]
from sc c
join course o on c.cno=o.cno
group by c.cno,o.cname
21、查询各科成绩前三名的记录:(不考虑成绩并列情况)
select s.score,s.cno
from sc s
left join sc c on c.cno=s.cno and c.score<s.score
group by s.score,s.cno
having count(c.cno)<3
order by s.cno
22、查询每门课程被选修的学生数
select o.cname 课程,count(s.cno) 人数
from sc s
right join course o on s.cno=o.cno
group by o.cname
23、查询出只选修了一门课程的全部学生的学号和姓名
select s.sno 学号,s.sname 姓名
from student s
inner join sc c on c.sno =s.sno
--group by c.cno, s.sno,s.sname
--having count(c.cno)=1
where c.sno in (
select t.sno from sc t
group by t.sno
having count(t.sno)=1
)
24、查询男生、女生人数
select t.ssex 性别, count(t.ssex) 人数 from student t
group by t.ssex
25、查询姓“张”的学生名单
select s.sname from student s
where s.sname like '张%'
26、查询同名同性学生名单,并统计同名人数
select t.sname,count(t.sname)
from student t
left join student s on s.sname=t.sname and s.ssex=s.ssex
group by t.sname
having count(t.sname)>1
27、1981 年出生的学生名单(注:Student 表中Sage 列的类型是numeric)
28、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列
select avg(c.score) from sc c
group by c.cno
order by avg(c.score) asc,c.cno desc
29、查询平均成绩大于85 的所有学生的学号、姓名和平均成绩
select t.sno,t.sname,avg(s.score) from student t
left join sc s on s.sno=t.sno
where t.sno in (
select c.sno from sc c
group by c.sno
having avg(c.score)>60
)
group by t.sno,t.sname
30、查询课程名称为“数据库”,且分数低于60 的学生姓名和分数
select t.sname,s.score from student t
left join sc s on t.sno=s.sno
where s.cno in(
select o.cno from course o
where o.cname='SQL SERVER 2005'
) and s.score<60
31、查询所有学生的选课情况;
select t.sname,count(s.cno) from student t
left join sc s on t.sno=s.sno
group by t.sno,t.sname
32、查询任何一门课程成绩在70 分以上的姓名、课程名称和分数;
select s.sname 姓名,o.cname 课程名称,c.score 课程成绩 from student s
left join sc c on c.sno=s.sno
left join course o on c.cno=o.cno
group by c.sno,s.sname,o.cname,c.score
having c.score>70
33、查询不及格的课程,并按课程号从大到小排列
select o.cname 课程名称 from sc s
left join course o on o.cno=s.cno
where s.score<60
order by s.cno desc
34、查询课程编号为c001 且课程成绩在80 分以上的学生的学号和姓名;
select s.sno 学号,s.sname 名称
from student s
left join sc c on c.sno=s.sno
where c.score>80 and c.cno='c001'
--
35、求选了课程的学生人数
select count(distinct s.sno) from sc s
36、查询选修“谌燕”老师所授课程的学生中,成绩最高的学生姓名及其成绩
select top 1 s.sname 姓名,c.score 成绩 from student s
left join sc c on c.sno=s.sno
left join course o on o.cno=c.cno
left join teacher t on t.tno=o.tno
where t.tname='谌燕'
order by c.score desc
37、查询各个课程及相应的选修人数
select o.cname 课程,count(s.cno) 人数 from sc s
left join course o on o.cno=s.cno
group by o.cname
38、查询不同课程成绩相同的学生的学号、课程号、学生成绩
select distinct s.sno 学号,c.score 课程号,o.cname 学生成绩 from student s
left join sc c on c.sno=s.sno
left join course o on o.cno=c.cno
where c.sno in
(
select distinct a.sno from sc a
left join sc b on b.sno=a.sno and b.cno !=a.cno
where a.score=b.score
)
39、查询每门功课成绩最好的前两名
select s.cno,s.sno from sc s
left join sc c on c.cno=s.cno and c.score<s.score
group by c.cno ,s.cno,s.sno
having count(c.cno)<3
order by s.cno desc
40、统计每门课程的学生选修人数(超过10 人的课程才统计)。 --要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列
lselect s.cno 课程号,count(s.cno) 参与人数 from sc s
group by s.cno
having count(s.cno)>=10
order by count(s.score) desc,s.cno asc
41、检索至少选修两门课程的学生学号
select s.sno from sc s
group by s.sno
having count(s.cno)>2
42、查询全部学生都选修的课程的课程号和课程名
select o.cno,o.cname from course o
43、查询没学过“谌燕”老师讲授的任一门课程的学生姓名
select distinct s.sno,s.sname from student s
left join sc c on c.sno=s.sno
left join course o on c.cno=o.cno
left join teacher t on t.tno=o.tno
where t.tname='刘阳'
44、查询两门以上不及格课程的同学的学号及其平均成绩
select s.sno,avg(s.score) 平均成绩
from sc s
where s.sno in(
select c.sno from sc c
where c.score<60
group by c.sno
having count(c.sno)>1
)
group by s.sno
45、检索“c004”课程分数小于60,按分数降序排列的同学学号
select sc.sno 学号 from sc
where sc.score<60 and sc.cno='c004'
order by sc.score desc
46、删除“s002”同学的“c001”课程的成绩
delete from sc
where sc.sno='s002' and sc.cno='c001'