oracle 数据库增删改查练习50例2.pdf
-- 一、建表 -- 1、根摇下面的内容创建表student drop table student; create table student ( sno varchar2(20),-- primary key , sname varchar2(10), sage DATE, ssex varchar2(10) ) comment on column student.sno is '学号'; comment on column student.sname is '姓名'; comment on column student.sage is '出生日期'; comment on column student.ssex is '性别'; desc SYSTEM.student: insert into SYSTEM.student values ('01','赵雷',to_date(19900101,'yyyymmdd'),'男'); insert into SYSTEM.student values ('02','钱电',to_date(19901221,'yyyymmdd'),'男'); insert into SYSTEM.student values ('03','孙风',to_date(19900520,'yyyymmdd'),'男'); insert into SYSTEM.student values ('04','李去',to_date(19900806,'yyyymmdd'),'男'); insert into SYSTEM.student values ('05','周梅',to_date(19911201,'yyyymmdd'),'女'); insert into SYSTEM.student values ('06','吴兰',to_date(19920301,'yyyymmdd'),'女'); insert into SYSTEM.student values ('07','郑竹',to_date(19890701,'yyyymmdd'),'女'); insert into SYSTEM.student values ('08','王菊',to_date(19900120,'yyyymmdd'),'女'); select * from student; -- 2、通过 pl/sql 工具生成增刚放查等客种语句 select sno, sname, sage, ssex from student; insert into student (sno, sname, sage, ssex) values (v_sno, v_sname, v_sage, v_ssex); update student set sno = v_sno, sname = v_sname, sage = v_sage, ssex = v_ssex where ; delete student where ; drop table student; create table student ( sno varchar2(20), sname varchar2(10), sage DATE, ssex varchar2(10) ) tablespace TEST_TS; -- create tablespace TEST_TS, -- 3、建立表course desc course; drop table course; create table course ( cno varchar2 (10), cname varchar2 (10), tno varchar2(10) ) comment on column course.cno is '学科号'; comment on column course.cname is '学科'; comment on column course.tno is '教师号'; insert into course values ('01','语文','02'); insert into course values ('02','数学','01'); insert into course values ('03','英语','03'); select * from course; -- 4、教师表 teacher drop table teacher; create table teacher ( tno varchar2 (10), tname varchar2(10) ); insert into teacher values('01','张三'); insert into teacher values('02','李四'); insert into teacher values('03','王五'); select * from teacher; -- 5、成绩表 drop table sc; truncate table sc; create table sc ( sno varchar2 (10), cno varchar2(10), score number (18,1) ); insert into sc values('01','01',80.0); insert into sc values('01','02',90.0); insert into sc values('01','03',99.0); insert into sc values('02','01',70.0); insert into sc values('02','02',60.0); insert into sc values('02','03',80.0); insert into sc values('03','01',80.0); insert into sc values('03','02',80.0); insert into sc values('03','03',80.0); insert into sc values('04','01',50.0); insert into sc values('04','02',30.0); insert into sc values('04','03',20.0); insert into sc values('05','01',76.0); insert into sc values('05','02',87.0); insert into sc values('06','01',31.0); insert into sc values('06','03',34.0); insert into sc values('07','02',89.0); insert into sc values('07','03',98.0); select * from sc; -- 二、查询 -- 1、查询 '01' '02' 课程分数 -- 1.1、查询同时存在 "01" 课程和 "02" 课程的情况 select * from student; select * from course; select * from teacher; select * from sc; select a.*,b.score 课程01的分数,c.score 课程02的分数 from student a inner join (select * from sc where cno='01') b on a.sno=b.sno inner join (select * from sc where cno='02') c on a.sno=c.sno; -- 1.2、查询必须存在"01"课程,"02"课程可以没有的情况 -- (不存在时显示为 null)(以下存在相同内容时不再解释); select a.*,b.score 课程01的分数,c.score 课程02的分数 from student a inner join (select * from sc where cno='01') b on a.sno=b.sno left join (select * from sc where cno='02') c on a.sno=c.sno; --2、查询'01'课程比'02'课程成绩低的学生的信息及课程分数 --2.1、查询同时'01'课程比'02'课程分数低的数据 select a.*,b.score 课程01的分数,c.score 课程02的分数 from student a inner join (select * from sc where cno='01') b on a.sno=b.sno inner join (select * from sc where cno='02') c on a.sno=c.sno where b.score < c.score; -- 2.2、查询同时'01'课程比'02'课程分数低或'01'缺考的数据 select a.*,b.score 课程01的分数,c.score 课程02的分数 from student a left join (select * from sc where cno='01') b on a.sno=b.sno inner join (select * from sc where cno='02') c on a.sno=c.sno where b.score < c.score or b.score is null; -- 3、查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩 select * from (select a.sno,a.sname,round(avg(sc.score),2) as average from student a left join sc on a.sno=sc.sno group by a.sno,a.sname )tab where tab.average >=60; -- 4、查询平均成绩小于 60 分的同学的学生编号和学生姓名和平均成绩 -- 4.1、有考试成绩,且小于 60 分 select * from (select a.sno,a.sname,round(avg(sc.score),2) as average from student a left join sc on a.sno=sc.sno group by a.sno,a.sname )tab where tab.average<60; -- 4.2、包括没有考试成绩的数据 select tab.sno,tab.sname,NVL(tab.average,0) from (select a.sno,a.sname,round(avg( sc.score ),2) as average from student a left join sc on a.sno=sc.sno group by a.sno,a.sname )tab where tab.average<60 or tab.average is null; -- 5、查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩 -- 5.1、查询所有成绩的(不含缺考的)。 select a.sno,a.sname,count(a.sno) 选课总数 ,sum(sc.score) 课程的总成绩 from student a left join sc on a.sno=sc.sno group by a.sno,a.sname having sum(sc.score) is not null; -- 5.2、查询所有成绩的(包括缺考的) select a.sno,a.sname,count(a.sno) 选课总数 ,sum(sc.score) 课程的总成绩 from student a left join sc on a.sno=sc.sno group by a.sno,a.sname -- 6、查询"李"姓老师的数量 (有几个老师姓李) select count(0) from teacher where substr(tname,1,1) = '李' -- 7、哪些学生上过张三(老师)的课 select student.* from student inner join ( select * from sc where cno= (select cno from (select * from teacher where tname='张三') a left join course b on a.tno=b.tno ) )s on s.sno = student.sno -- 8、哪些学生没上过张三(老师)的课 select student.* from student where sno not in ( select sno from sc where cno = (select cno from (select * from teacher where tname='张三') a left join course b on a.tno=b.tno ) ) -- 9、查询 '01' '02'都学过的同学的信息 select a.* from student a inner join (select * from sc where cno='01') b on a.sno=b.sno inner join (select * from sc where cno='02') c on a.sno=c.sno -- 10、查询学过编号为'01'但是没有学过编号为'02'的课程的同学的信息 select a.* from student a left join (select * from sc where cno='01') b on a.sno=b.sno left join (select * from sc where cno='02') c on a.sno=c.sno where b.score is not null and c.score is null -- 11、查询没有学全所有课程的同学的信息 -- 11.1 学完所有课程的 select a.* from student a inner join (select * from sc where cno='01') b on a.sno=b.sno inner join (select * from sc where cno='02') c on a.sno=c.sno inner join (select * from sc where cno='03') d on a.sno=d.sno -- 11.2 没有学完所有课程的 select a.* from student a left join (select * from sc where cno='01') b on a.sno=b.sno left join (select * from sc where cno='02') c on a.sno=c.sno left join (select * from sc where cno='03') d on a.sno=d.sno where b.score is null or c.score is null or d.score is null -- 12、查询至少有一门课与学号为'01'的同学所学相同的同学的信息 select * from student where sno in ( select distinct sno from sc where cno in (select sc.cno from sc where sc.sno='01') and sno != '01' ) -- 13、查询和'01'号的同学学习的课程完全相同的其他同学的信息 !! select * from student where sno in ( select sno from sc where cno in (select sc.cno from sc where sc.sno='01') and sno != '01' group by sno having count(cno) >= 3 ) -- 14、查询没学过"张三"老师讲授的任一门课程的学生姓名 select * from student where sno not in ( select distinct sno from sc where cno in ( select cno from course where tno = (select tno from teacher where tname = '张三') ) ); -- 15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩 select a.sno,a.sname,b.avg_score from student a inner join (select sno,round(avg(score),2) avg_score from sc group by sno) b on a.sno = b.sno where a.sno in (select sno from sc where score < 60 group by sno having count(sno) >= 2); -- 16、检索'01'课程分数小于 60,按分数降序排列的学生信息 select a.* ,b.score from student a inner join (select * from sc where cno = 01 and score < 60) b on a.sno = b.sno order by b.score desc; -- 17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩 select a.sno,a.sname,b.score 课程01的分数,c.score 课程02的分数,d.score 课程03的分数,avg_score from student a left join (select * from sc where cno='01') b on a.sno=b.sno left join (select * from sc where cno='02') c on a.sno=c.sno left join (select * from sc where cno='03') d on a.sno=d.sno left join (select sno,round(avg(score),2) avg_score from sc group by sno) e on a.sno=e.sno order by e.avg_score desc; -- 18、查询各科成绩最高分、最低分和平均分: -- 以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率 -- 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90 select a.cno,cname,a.最高分,a.最低分,a.平均分,b.及格率,b.中等率,b.优良率,b.优秀率 from course left join ( select cno,max(score) 最高分,min(score) 最低分,round(avg(score),2) 平均分 from sc group by cno ) a on course.cno = a.cno left join ( select cno,round(sum(case when score>=60.0 then 1 else 0 end)/count(0)*100,2) as 及格率, round(sum(case when score>=70.0 and score <80 then 1 else 0 end)/count(0)*100,2) as 中等率, round(sum(case when score>=80.0 and score <90 then 1 else 0 end)/count(0)*100,2) as 优良率, round(sum(case when score>=90.0 then 1 else 0 end)/count(0)*100,2) as 优秀率 from sc group by cno ) b on a.cno = b.cno -- 19、按各科成绩进行排序,并显示排名 select sc.*,rank()over(partition by cno order by score desc) px from sc; -- 20、查询学生的总成绩并进行排名 -- 20.1、 查询学生的总成绩 select a.sno,a.sname,NVL(b.总成绩,0) 总成绩 from student a left join (select sno,sum(score) 总成绩 from sc group by sno) b on a.sno = b.sno order by 总成绩 desc; -- 20.2、查询学生的总成绩并进行排名。 select tab.*,rank()over(order by tab.总成绩 desc) px from (select a.sno,a.sname,NVL(b.总成绩,0) 总成绩 from student a left join (select sno,sum(score) 总成绩 from sc group by sno) b on a.sno = b.sno)tab; -- 21、查询不同老师所教不同课程平均分从高到低显示 select a.tno,tname,avg_score from teacher a left join course b on a.tno = b.tno left join (select cno,round(avg(score),2) avg_score from sc group by cno) c on b.cno=c.cno order by avg_score desc; -- 22、查询所有课程的成绩第 2 名到第 3 名的学生信息及该课程成绩 -- Score 重复时保留名次空缺 select * from (select sc.*,rank()over(partition by cno order by score desc)px from sc) a where px>=2 and px<=3; -- Score 重复时合并名次 select * from (select sc.*,dense_rank()over(partition by cno order by score desc)px from sc) a where px>=2 and px<=3; -- 23 、统计各科成绩 各分数段人数:课程编号, 课程名称, "100-85","85-70","70-60","0-60"及所占百分比 -- 23.1 统计各科成绩 各分数段人数:课程编号, 课程名称, "100-85","85-70","70-60","0-60" -- 横向显示 select a.cname,b.* from course a left join ( select cno,sum(case when score>=85 then 1 else 0 end) "100-85" , sum(case when score<85 and score>=70 then 1 else 0 end) "85-70" , sum(case when score<70 and score>=60 then 1 else 0 end) "70-60" , sum(case when score<60 and score>=0 then 1 else 0 end) "0-60" from sc group by cno )b on a.cno = b.cno; -- 纵向显示 1(显示存在的分数段); !! select a.cno 课程编号, a.cname 课程名称, (case when b.score >= 85 then '85-100' when b.score >= 70 and b.score < 85 then '70-85' when b.score >= 60 and b.score < 70 then '60-70' else '0-60' end) 分数段, count(1) 数量 from course a , sc b where a.cno = b.cno group by a.cno , a.cname , ( case when b.score >= 85 then '85-100' when b.score >= 70 and b.score < 85 then '70-85' when b.score >= 60 and b.score < 70 then '60-70' else '0-60' end) order by a.cno , a.cname , 分数段 -- 24、 查询学生的平均成绩并进行排名 select tab.*, rank()over(order by avg_score desc) px from ( select a.sno,a.sname,NVL(b.avg_score,0) avg_score from student a left join (select sno,round(avg(score),2) avg_score from sc group by sno)b on a.sno = b.sno )tab; -- 25、查询各科成绩前三名的记录 -- 25.1 分数重复时保留名次空缺 select b.sno,student.sname,student.sage,student.ssex,b.cno,b.score from ( select * from (select sc.*, rank()over(partition by cno order by score desc) px from sc) a where a.px <4 )b inner join student on b.sno = student.sno; -- 25.2 分数重复时不保留名次空缺,合并名次 select b.sno,student.sname,student.sage,student.ssex,b.cno,b.score from ( select * from (select sc.*, dense_rank()over(partition by cno order by score desc) px from sc) a where a.px <4 )b inner join student on b.sno = student.sno; -- 26、查询每门课程被选修的学生数 select cno,count(0) 学生数 from sc group by cno; -- 27、查询出只有两门课程的全部学生的学号和姓名 select student.sno,student.sname from student inner join ( select sno,count(0) from sc group by sno having count(0)=2 )a on student.sno=a.sno; -- 28、查询男生、女生人数 select ssex,count(0) 人数 from student group by ssex; -- 29、查询名字中含有"风"字的学生信息 select * from student where sname like '%风%'; -- 31、查询 1990 年出生的学生名单(注:Student 表中 Sage 列的类型是 date) select * from student where to_char(sage,'yyyy')='1990'; -- 32、查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时, -- 按课程编号升序排列 select cno,round(avg(score),2) avg_score from sc group by cno order by avg_score desc,cno; -- 33、查询平均成绩大于等于 85 的所有学生的学号、姓名和平均成绩 select s.sno,s.sname,a.avg_score from student s inner join (select sno,round(avg(score),2) avg_score from sc group by sno having round(avg(score),2)>=85)a on s.sno = a.sno; -- 34、查询课程名称为"数学",且分数低于 60 的学生姓名和分数 select sname,b.score from student s inner join (select * from sc where cno= (select cno from course where cname = '数学' ) and score<60 )b on s.sno = b.sno; -- 35、查询所有学生的课程及分数情况; select s.*,c.cname,sc.score from student s left join sc on s.sno = sc.sno left join course c on sc.cno = c.cno; -- 36、查询任何一门课程成绩在 70 分以上的姓名、课程名称和分数; select s.sname,c.cname,a.score from student s left join (select sno,cno,score from sc where score >=70) a on s.sno = a.sno left join course c on a.cno = c.cno; -- 37、查询不及格的课程 select s.*,c.cname,a.score from student s inner join (select * from sc where score < 60) a on s.sno = a.sno left join course c on a.cno = c.cno; -- 38、查询课程编号为 01 且课程成绩在 80 分以上的学生的学号和姓名; select s.sno,s.sname from student s inner join (select * from sc where cno = '01' and score >= 80) a on s.sno = a.sno; -- 39、求每门课程的学生人数 select c.cno,c.cname,a.ct 学生人数 from course c inner join (select cno,count(0) ct from sc group by sc.cno) a on c.cno = a.cno; -- 40、查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩 !! /* select sno,score from sc where cno in ( select cno from course c where tno= (select tno from teacher where tname = '张三') ) order by score desc limit 1; */ SELECT stu.sname,s.score,c.cname FROM student stu inner JOIN sc s ON stu.sno=s.sno inner JOIN course c ON s.cno=c.cno inner JOIN teacher t ON t.tno=c.tno WHERE t.tname='张三' AND s.score=(SELECT MAX(score) FROM sc WHERE cno= (SELECT cno FROM course WHERE tno=(SELECT tno FROM teacher WHERE tname='张三'))); -- 41、查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩 !! select * from sc s1 join sc s2 on s1.score = s2.score and s1.cno != s2.cno -- 42、查询每门功成绩最好的前两名 select * from (select sc.*,rank()over(partition by cno order by score desc) px from sc)a where px <3 -- 44、检索至少选修两门课程的学生学号 select sno,count(0) from sc group by sno having count(0)>=2 -- 46、查询各学生的年龄 select s.*,(CAST((EXTRACT(YEAR FROM CURRENT_DATE)) AS integer)-CAST((EXTRACT(YEAR FROM sage)) AS integer)) AS 年龄 from student s SELECT Sno, Sname, Sage, EXTRACT(YEAR FROM CURRENT_TIMESTAMP) - EXTRACT(YEAR FROM Sage) AS 年龄 FROM Student; select sno,sname,year(curdate())-year(sage) as sage from student -- 47、查询本周过生日的学生 !! select * from student where to_date(substr(sage,6,10),'mm-dd')>= trunc(next_day(sysdate-8,1)+1) and to_date(substr(sage,6,10),'mm-dd') < trunc(next_day(sysdate-8,1)+7)+1; select * from student -- 48、查询下周过生日的学生 !! select * from student where to_date(substr(sage,6,10),'mm-dd')>= trunc(next_day(sysdate-8,1)+8) and to_date(substr(sage,6,10),'mm-dd') < trunc(next_day(sysdate-8,1)+14)+1; -- 49、查询本月过生日的学生 select * from student where extract(month from(sysdate)) = extract(month from sage) -- 50、查询下月过生日的学生 select * from student where (extract(month from(sysdate))+1) = extract(month from sage)