博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

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)

  

 

posted @ 2023-03-06 20:25  CHANG_09  阅读(166)  评论(0编辑  收藏  举报