声明:该文档主要根据网上一份题目整理而成。给出的答案仅供参考。
假设有下面4张表
student(sid,sname,sage,ssex) 学生表
course(cid,cname,tid) 课程表
grade(sid,cid,score) 成绩表
teacher(tid,Tname) 教师表
问题:
1、 查询“001”课程比“002”课程成绩高的所有学生的学号
#方式1
select a.sid
from grade a,grade b
where a.sid=b.sidand a.cid=2 and b.cid=3 and a.score>b.score;
#方式2
select a.sid
from (select sid,score from grade where cid=2) a,
(select sid,score from grade where cid=3) b
where a.sid=b.sidand a.score>b.score;
2、 查询平均成绩大于60分的同学的学号和平均成绩;
select sid,avg(score) as avg
from grade
group by sid
havingavg>60;
3、 查询所有同学的学号、姓名、选课数、总成绩;
#方式1
select s.sid,s.sname,count(cid),sum(score)
from student s
left join grade g
on s.sid=g.sid
group by s.sid;
#方式2
select s.sid,s.sname,a.num,a.totals
from student s
left join (select sid,count(cid) as num,
sum(score) as totals from grade group by sid)as a
on s.sid=a.sid;
#方式3
select s.sid,s.sname,(select count(cid)from grade where sid=s.sid) as num,
(select sum(score) from grade where sid=s.sid)as totals
from student s;
4、 查询姓“李”的老师的个数;
select count(tname)
from teacher
where tname like '李%';
5、查询没学过“ta”老师课的同学的学号、姓名;
#方式1
select sid,sname
from student
where sid not in
(select sid from grade where cid in
(select cid from course c,teacher t wherec.tid=t.tid and t.tname='ta')
);
#方式2
select sid,sname
from student
where sid not in
(selectdistinct sid from grade g,course c,teacher t where g.cid=c.cid and c.tid=t.tidand t.tname='ta');
6、查询学过“002”并且也学过编号“003”课程的同学的学号、姓名;
#方式1
select sid,sname
from student
where sid in (
select a.sid
from (select sid from grade where cid=2) a,(select sid from grade where cid=3) b
wherea.sid=b.sid);
#方式2
select sid,sname
from student
where sid in (select sid from grade wherecid=2)
and
sid in (select sidfrom grade where cid=3);
#方式3
select s.sid,sname
from student s,grade g
where s.sid=g.sid and g.cid=2 and
s.sid in (select sid from grade wherecid=3);
#方式4
select s.sid, sname
from student s,grade g
where s.sid=g.sid and g.cid=2 and
exists( Select * from grade as g2 where g2.sid=g.sidand g2.cid=3);
7、查询学过“tb”老师所教的所有课的同学的学号、姓名;
#方式1
#利用sum统计每个同学上tb老师课的门数,选出那些门数=tb所教课的门数
Select sid,sname
from student
where sid in
(select sid
from grade
group by sid
having sum(case when cid in (select cidfrom Course c,Teacher t where T.tid=C.tid and Tname='tb') then 1 else 0 end)
=(select count(cid) from Course c,Teacher twhere T.tid=C.tid and Tname='tb')
);
#方式2
select sid,sname
from Student
where sid in
(select sid
from GRADE g,Course c,Teacher t
where g.cid=C.cid and c.tid=t.tid andTname='tb'
group by sid
having count(g.cid)=
(select count(cid) from Course c,Teacher twhere T.tid=C.tid and Tname='tb')
);
8、查询那些所有课程成绩小于60分的同学的学号、姓名;
#方式1
select s.sid,sname
from student s,grade g
where s.sid=g.sid and s.sid not in (select sidfrom grade where score>=60);
#方式2
select s.sid, sname
from student s,grade g
where s.sid=g.sid
group by s.sid
havingmax(score)<60;
9、查询没有学全所有课的同学的学号、姓名;
#方式1
select s.sid,sname
from student s
left join grade g
on s.sid=g.sid
group by s.sid
havingcount(cid)<(select count(distinct cname) from course);
#方式2
select sid,sname
from student
where sid not in (
select sid
from grade
group by sid
havingcount(cid)=(select count(distinct cname) from course));
10、查询至少有一门课与学号为“1”的同学所学相同的同学的学号和姓名;
#方式1
select distinct s.sid,sname
from student s,grade g
where s.sid=g.sid and s.sid<>1 andcid in (select cid from grade where sid=1);
#方式2
select sid,sname
from student
where sid in (
select sid
from grade
where sid<>1 and cid in (select cidfrom grade where sid=1)
);
11、查询至少学过学号为“005”同学所有课的其他同学学号和姓名;
#方式1
Select s.sid,sname
From student s, grade g, (select cid fromgrade where sid=5) as a
Where s.sid=g.sid and g.cid=a.cid ands.sid<>5
Group by s.sid
Having count(g.cid)=
(select count(b.cid) from (select cid fromgrade where sid=5) as b);
12、把“GRADE”表中“tb”老师教的课的成绩都更改为此课程的平均成绩;
#方式1
Update grade as g1,
(select g.cid, avg(score) avg from gradeg,course c,teacher t where g.cid=c.cid and c.tid=t.tid and t.tname=’tb’ groupby g.cid) as a
Set g1.score=a.avg
Where g1.cid=a.cid
#方式2,虽然巧,但是效率低
Update grade as g
set g.score=
(select a.avg
From (select cid,avg(score) as avg from grade group by cid) as a
Where g.cid=a.cid)
Where g.cid in (Select cid from course c,teacher twhere c.tid=t.tid and t.tname='tb');
13、查询和“1”号的同学学习的课程完全相同的其他同学学号;
#方式1
#巧妙的数学逻辑
select distinct sid
from grade
where sid <>1 and sid not in (
select sid from grade where cid not in (
select cid from grade where sid=1))
group by sid
havingcount(sid)= (select count(cid) from grade where sid=1);
14、删除学习“ta”老师课的GRADE表记录;
#方式1
delete
from grade
where cid in (select cid from coursec,teacher t where c.cid=t.tid and t.tname='ta');
#方式2
delete g
from grade g,course c,teacher t
whereg.cid=c.cid and c.tid=t.tid and t.tname='ta';
15、向GRADE表中插入一些记录(包含以下3个字段):
没有上过编号“001”课程的同学学号,1号课,1号课的平均成绩;
insert into grade
select sid,1,(select avg(score) from gradewhere cid=1)
from student
where sid notin (select sid from grade where cid=1);
16、按所有课程平均成绩从高到低显示所有学生的“math”、“phy”、“che”三门的课程成绩,按如下形式显示:
学生ID,,math,phy,che,有效课程数,有效平均分
Select s.sid,
(select score from grade,course wheregrade.sid=s.sid and grade.cid=course.cid and course.cname='math') as 'math',
(select score from grade,course wheregrade.sid=s.sid and grade.cid=course.cid and course.cname='phy') as 'phy',
(select score from grade,course wheregrade.sid=s.sid and grade.cid=course.cid and course.cname='che') as 'che',
(select count(cid) from grade where sid=s.sid)as num,
(select avg(score) from grade where sid=s.sid)as avg
From student s
order by avg desc;
17、查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
select c.cid,max(score) as max,min(score)as min
from course c
left join grade g
on c.cid=g.cid
group by c.cid;
18、按各科平均成绩从低到高和及格率的百分数从高到低顺序
#方式1
select g.cid, avg(g.score) as avg,100*(selectcount(sid) from grade where cid=g.cid and score>=60)/count(sid) as rate
from grade g
group by cid
order by avgasc, rate desc;
#方式2
#利用sum函数和分支语句,sum(1) 貌似与 count(*) 效果一样
select g.cid, avg(g.score) asavg,100*sum(case when score>=60 then 1 else 0 end)/sum(1) as rate
from grade g
group by cid
order by avgasc, rate desc;
19、查询如下课程平均成绩和及格率的百分数(用"1行"显示): math(001),phy(002)
#方式1
select
(select avg(score) from grade where cid=1)as mathavg,
((select count(sid) from grade where cid=1and score>=60)/(select count(sid) from grade where cid=1)) as mathrate,
(select avg(score) from grade where cid=2)as phyavg,
((select count(sid)from grade where cid=2 and score>=60)/(select count(sid) from grade wherecid=2)) as phyrate;
#方式2
#利用sum函数和分支语句进行全局统计
SELECT
SUM(CASE WHEN cid =1 THEN score ELSE 0END)/SUM(CASE cid WHEN 1 THEN 1 ELSE 0 END) AS mathavg,
100 * SUM(CASE WHEN cid =1 AND score >=60 THEN 1 ELSE 0 END)/SUM(CASE WHEN cid =1 THEN 1 ELSE 0 END) AS mathrate,
SUM(CASE WHEN cid = 2 THEN score ELSE 0END)/SUM(CASE cid WHEN '002' THEN 1 ELSE 0 END) AS phyavg,
100 * SUM(CASE WHEN cid = 2 AND score >=60 THEN 1 ELSE 0 END)/SUM(CASE WHEN cid = 2 THEN 1 ELSE 0 END) AS phyrate
FROM GRADE
20、查询不同老师所教不同课程平均分从高到低显示
#方式1
select c.tid, c.cid, avg(g.score) as avg
from course c,grade g
where c.cid=g.cid
group by c.tid, c.cid
order by c.tid,avg desc
21、查询各科成绩前三名的记录:(不考虑成绩并列情况)
#方式1(错误)
#mysql 不支持在子查询中取一定数量的记录,所以下面的语句逻辑上是对的,执行是错的
select g.cid,sid,score
from grade g
where sid in (select sid from grade wherecid=g.cid order by score limit 3)
order by g.cid,score desc;
#方式2
#下面的语句很巧妙,一方面利用了传值计算判断,另一方面用了判断排名的技巧
select cid,sid,score
from grade g
where 2>=(select count(sid) from gradewhere score>g.score and cid=g.cid )
order by cid,score desc;
#方式3
#下面的语句也很巧妙,一方面,没有用传值判断,因为用两张大表左关联代替,另一方面,判断排名的技巧同上
select a.sid, a.cid,a.score
from grade a
left join grade b
on a.cid=b.cid and a.score group by a.sid, a.cid,a.score having count(b.sid)<=2 order bya.cid,a.score desc; #方式4 ,下面的语句在Oracle上可运行 selectcid,sid ,score from (select cid,sid,score, row_number()OVER(PARTITION BY cid ORDER BY score DESC) rid FROMgrade) where rid<=3; 23、统计各科成绩各分数段人数:课程ID,课程名称,[100-85],[84-60],[ <60] #方式1 #利用sum函数和分支语句 select g.cid,cname, sum(case when score>=85 then 1 else 0end ) as '[85-100]', sum(case when score <85 and score>=60then 1 else 0 end) as '[60-84]', sum(case when score<60 then 1 else 0end) as'[0-59]' from grade g,course where g.cid=course.cid group by g.cid; 24、查询学生平均成绩及其名次 #方式1 #很巧妙,先构造(学生,平均成绩)表,然后为排名构造一个技巧 select 1+(select count(b.avg) from (select sid,avg(score)as avg from grade group by sid) as b where b.avg > a.avg) as ranking, sid,a.avg from (select sid,avg(score) as avg fromgrade group by sid) as a order byranking; 26、查询每门课程被选修的学生数 select cid,count(sid) from grade group by cid; 27、查询出只选修了一门课程的全部学生的学号和姓名 select g.sid,s.sname from grade g,student s where g.sid=s.sid group by g.sid having count(cid)=1; 28、查询男生、女生人数 select ssex,count(sid) from student group by ssex; 29、查询姓“张”的学生名单 select sid,sname from student where snamelike '张%' 30、查询同名同姓学生名单,并统计同名人数 select sname,count(sid) as num from student group by sname having num>1; 32、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列 select cid,avg(score) as avg from grade group by cid order by avgdesc,cid asc; 33、查询平均成绩大于85的所有学生的学号、姓名和平均成绩 select s.sid,sname,avg(score) as avg from student s,grade g where s.sid=g.sid group by s.sid havingavg>85; 34、查询课程名称为“phy”,且分数低于60的学生姓名和分数 select sname,score from student s,grade g,course c where s.sid=g.sidand g.cid=c.cid and c.cname='phy' and g.score<60; 35、查询所有学生的选课情况; # 方式1 select s.sid,sname,g.cid,cname from student s,grade g,course c where s.sid=g.sid and g.cid=c.cid order by s.sid,g.cid; #方式2 select s.sid,s.sname,a.cid,a.cname from student s left join (select sid,g.cid,cname fromgrade g,course c where g.cid=c.cid) a on s.sid=a.sid order by s.sid,a.cid; 36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数; select s.sid,sname,cname,score from student s,grade g,course c where s.sid=g.sid and g.cid=c.cid andscore>70 order by s.sid; 37、查询有不及格学生的课程,并按课程号从大到小排列 select cid from grade where score<60 order by ciddesc; 38、查询课程编号为003且课程成绩在80分以上的学生的学号和姓名; select s.sid,s.sname from student s,grade g where s.sid=g.sidand score>80 and g.cid=3; 39、求选了课程的学生人数 select count(distinct sid) from grade; 40、查询选修“tb”老师所授课程的学生中,成绩最高的学生学号、姓名、课程编号及其成绩 本题有两种理解,一是不区分tb所教不同课程,求出最高分;二是进行区分,分别求出不同课程的最高分 #方式1,不区分 select cid,s.sid,sname ,score from grade g,student s where g.sid=s.sid and g.cid in (select cid from course c,teacher t wherec.tid=t.tid and tname='tb') andscore=(select max(score) from grade where cid in (select cid from course c,teacher t where c.tid=t.tidand tname='tb')); #方式2,不区分 Select g.cid,s.sid,sname,score from student s,grade g,course c,teacher t where s.sid=g.sid and g.cid=c.cid andc.tid=t.tid and t.tname='tb' and score= (selectmax(score) from grade g1,course c1,teacher t1 where g1.cid=c1.cid andc1.tid=t1.tid and t1.tname='tb'); #方式3,区分 Select g.cid,s.sid,sname,score from student s,grade g,course c,teacher t where s.sid=g.sid and g.cid=c.cid andc.tid=t.tid and t.tname='tb' and score= (selectmax(score) from grade where cid=g.cid); 41、查询各个课程及相应的选修人数 select cid,count(sid) from grade group by cid; 44、统计每门课程的学生选修人数(超过4人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列 select cid,count(sid) as num from grade group by cid having num>4 order by num desc, cid; 45、检索至少选修两门课程的学生学号 select sid from grade group by sid havingcount(cid)>=2 46、查询全部学生都选修的课程的课程号和课程名 select c.cid,cname from course c,grade g where c.cid=g.cid group by c.cid having count(sid)=(select count(sid) fromstudent); 47、查询没学过“ta”老师讲授的任一门课程的学生姓名 select sname from student where sid not in (select distinct sid from grade g,coursec,teacher t where g.cid=c.cid and c.tid=t.tid and t.tname='ta'); 48、查询至少有一门不及格课程的同学的学号及其平均成绩 select sid,avg(score) from grade where sid in (select sid from grade wherescore<60 group by sid having count(cid)>0) group by sid; 50、删除“002”同学的“001”课程的成绩 delete from Grade where sid='002'andcid='001';