实验目的

不仅仅熟练掌握 SQL 的语法,更加主要目的熟练掌握各种常用的、逻辑复杂的 SQL。

经验之谈

实验期间,如果出现错误找不到,不要轻易怀疑答案,更不要怀疑 Oralce 数据库系统,工 作以后也要记住一句经验之谈,“一定是你错了,只是不知道自己错在哪里了”。

说在前面

我的答案一定不是最好的,希望看到这篇文章的同学不要只是复制答案,这样做没有意义,正确的做法是看到正确答案后自己独立思考理解答案,将知识变为自己的东西。

实验用表

pub.teacher_course

pub.teacher

pub.student_course

pub.student

pub.course

1-1
创建学生信息表(学生编号、姓名、性别、年龄、出生日期、院系名称、班级):
test1_student:sid char 12 not null、name varchar 10 not null、sex char 2、age int、
birthday date、dname varchar 30、class varchar 10。
建表语句常见错误如下:
关键词拼写错误,少关键词、少逗号、少括号。

create table test1_student
( sid char (12) not null ,
name varchar (10) not null ,
sex char (2) ,age int ,
birthday date ,
dname varchar (30) ,
class varchar (10) ) ;

1-2
创建课程信息表(仅考虑一门课程最多一个先行课的情况):
课程编号、课程名称、先行课编号、学分
test1_course:cid char 6 not null、name varchar 40 not null、fcid char 6、
credit numeric 4,1(其中4代表总长度,1代表小数点后面长度)。

create table test1_course
( cid char (6) not null ,
name varchar (40) not null ,
fcid char (6) ,
credit numeric (4,1) ) ;

1-3
创建学生选课信息表(学号、课程号、成绩、教师编号、选课时间)
test1_student_course:sid char 12 not null、cid char 6 not null、
score numeric 5,1(其中5代表总长度,1代表小数点后面长度)、tid char 6, sctime date

create table test1_course
( cid char (6) not null ,
name varchar (40) not null ,
fcid char (6) ,
credit numeric (4,1) ) ;

1-4
给表test1_student插入如下2行数据。
输入日期类型数据的格式,插入一句有严格语法格式,不要想当然自创语法格式。:
采用:insert into t1 values(‘200700030101’,‘赵中华’,‘男’,19,date ‘2012-02-02’,‘计算机学院’,‘2010’)
或者
采用:insert into t1 values(200700030101,‘赵中华’,‘男’,19,to_date(‘20120202’,‘yyyymmdd’),‘计算机学院’,‘2010’)

     学号          姓名  性别 年龄  出生日期  院系名称    班级

200800020101 王欣 女 21 1994/2/2 计算机学院 2010
200800020102 李华 女 20 1995/3/3 软件学院 2009

insert into test1_student
values (‘200800020101’,‘王欣’,‘女’,‘21’,date ‘1994-02-02’,‘计算机学院’,‘2010’ ) ;

1-5
给表test1_course插入如下2行数据。
注意空值的插入使用null
课程号 课程名 先行课程号 学分
300001 数据结构 2
300002 数据库 300001 2.5

insert into test1_course
values (‘300001’,‘数据结构’,null,‘2’)
insert into test1_course
values (‘300002’,‘数据库’,‘300001’,‘2.5’)

1-6
给表test1_student_course插入如下2行数据。
学号 课程号 成绩 教师编号 选课时间
200800020101 300001 91.5 100101 2009-7-15 09:09:09
200800020101 300002 92.6 100102 2009-7-15 10:10:10

insert into test1_student_course
values ( ‘200800020101’,‘300002’,92.6,‘100102’,to_date(‘20090715101010’,‘yyyymmddhh24miss’) )

2-1
找出没有选修任何课程的学生的学号、姓名(即没有选课记录的学生)。
自己认为查询语句正确后,通过下面语句将查询语句创建成视图test2_01
Create or replace view test2_01 as select ……
然后就可以点击实验二的题目1的【交卷验证】,验证正确性,正确后就有得分。

create or replace view test2_01 as
select sid,name from pub.studentwhere sid not in (select sid from pub.student_course);

2-2
找出至少选修了学号为"200900130417"的学生所选修的一门课的学生的学号、姓名。
自己认为查询语句正确后,通过下面语句将查询语句创建成视图test2_02
Create or replace view test2_02 as select ……
然后就可以点击实验二的题目2的【交卷验证】,验证正确性,正确后就有得分。
以下各题操作类似。

create or replace view test2_02 as
(select sid,name
from pub.student
where sid in
( select sid
from pub.student_course
where cid in
(select cid
from pub.student_course
where sid=200900130417 ) ))
minus
(select sid,name
from pub.student
where sid=200900130417)//最后要去掉那一个学生,不包括该学号的学生

2-3
找出至少选修了一门其先行课程号为"300002"号课程的学生的学号、姓名。

create view test2_03 as
select sid ,name
from pub.student_course natural join pub.student
where cid in
( select cid
from pub.course
where fcid=‘300002’)

2-4
找出选修了"操作系统"并且也选修了"数据结构"的学生的学号、姓名。

Create or replace view test2_04 as
select s.sid,name
from pub.student S
where not exists
(( select cid
from pub.course
where name=‘数据结构’ or name=‘操作系统’ )
minus
( select cid
from pub.student_course T
where t.sid=s.sid))

2-5
查询20岁的所有有选课的学生的学号、姓名、平均成绩(avg_score,此为列名,下同)(平均成绩四舍五入到个位)、总成绩(sum_score)
Test2_05有四个列,并且列名必须是:sid、name、avg_score、sum_score。通过下面方式实现列名定义:
create or replace view test2_05 as select sid,name,(表达式) avg_score,(表达式) sum_score from ……

create or replace view test2_05 as
select sid,name,round(avg(score),0)avg_score,sum(score)sum_score
from pub.student natural join pub.student_coursewhere age=20
group by sid,name

2-6
查询所有课的最高成绩、最高成绩人数,test2_06有四个列:课程号cid、课程名称name、最高成绩max_score、最高成绩人数max_score_count(一个学生同一门课成绩都是第一,只计一次)。如果没有学生选课,则最高成绩为空值,最高成绩人数为零。
提示1:任何select 确保只返回一个结果 from …… where ……t1.xx=t2.xx
(条件中还可以出现主表的列来限制每行结果的不同)可以是另外一个select的一个输出表达式。格式如:select sid,(select……)
列别名 from …… where ……。
提示2:任何select 确保只返回一个结果 from …… where
……(不能引用主表来)可以出现在另外一个sql的条件表达式中。格式如:select …… from …… where
xx=(select……)。
提示3:任何select …… from …… where ……可以是另外一个sql的表,即派生表。格式如:select …… from
student,(select……)表别名 where ……。

create or replace view test2_06 as
select a.cid,a.name,max_score,max_score_count
from
( select cid,name
from pub.course) a,
( select cid,max(score) max_score
from pub.student_course
group by cid) b,
(
select sc.cid,count(distinct sid) max_score_count
from pub.student_course sc,
( select cid,max(score) max_score from pub.student_course
group by cid ) max_sc
where sc.cid=max_sc.cid and sc.score=max_sc.max_score
group by sc.cid) d
where a.cid=b.cidand b.cid=d.cid
//此题较难,建议多思考几遍

2-7
查询所有不姓张、不姓李、也不姓王的学生的学号sid、姓名name

create or replace view test2_07 as
(select sid,name
from pub.student)
minus
(select sid,name
from pub.student
where name like ‘张%’ or name like ‘李%’ or name like ‘王%’

2-8
查询学生表中每一个姓氏及其人数(不考虑复姓),test2_08有两个列:second_name、p_count

create or replace view test2_08 as
( select substr(name,1,1) second_name ,count(*) p_count
from pub.student
group by substr(name,1,1));
//用到了特殊的聚集函数

2-9
查询选修了300003号课程的学生的sid、name、score

create or replace view test2_09 as
select sid,name,score
from pub.student natural join pub.student_course
where cid=‘300003’

2-10
找出同一个同学同一门课程有两次或以上不及格的所有学生的学号、姓名(即一门课程需要补考两次或以上的学生的学号、姓名)

create or replace view test2_10 as
select sid,name
from pub.student
where sid in
(select sid from
( select pub.student_course.sid, pub.student_course.cid ,count(*) count
from pub.student_course
where score<60
group by pub.student_course.sid, pub.student_course.cid)
where count>=2);

3-1
将pub用户下的Student_31及数据复制到主用户的表test3_01,删除表中的学号不全是数字的那些错误数据,学号应该是数字组成,不能够包含字母空格等非数字字符。
方法之一:用substr函数,例如Substr(sid,1,1)返回学号的第一位,判断是否是数字。

create table test3_01 as
select * from pub.student_31
where regexp_like(sid,’1{12}′)此处使用正则表达式匹配,关键字regexplike(要匹配的对象,′[1]1[35]1[[:digit:]9') 此处使用正则表达式匹配,关键字regexp_like(要匹配的对象,'^[1]{1}[35]{1}[[:digit:]{9}′)此处使用正则表达式匹配,关键字regexpl​ike(要匹配的对象,′[1]1[35]1[[:digit:]9’) ^表示开始,$结束,[1]{1}表示有一位是1,[35]{1}表示有一位是3或5。[:digit:]是特殊的表示方法表示0-9这十个数字,[[:digit:]]{9}是指9位数字。

3-2
将pub用户下的Student_31及数据复制到主用户的表test3_02,删除表中的出生日期和年龄(截止到2012年的年龄,即年龄=2012-出生年份)不一致的那些错误数据。
函数extract(year from birthday)返回birthday的年份

create table test3_02 as
select * from pub.student_31
where 2012-extract(year from birthday)=age

3-3
将pub用户下的Student_31及数据复制到主用户的表test3_03,删除表中的性别有错误的那些错误数据(性别只能够是"男"、"女"或者空值)。

create table test3_03 as
select * from pub.student_31
where sex=‘男’ or sex=‘女’ or sex is null

3-4
将pub用户下的Student_31及数据复制到主用户的表test3_04,删除表中的院系名称有空格的、院系名称为空值的或者院系名称小于3个字的那些错误数据。

create table test3_04 as
select *from pub.student_31
where dname is not null and length(dname)>=3 and dname not like ‘% %’;

3-5
将pub用户下的Student_31及数据复制到主用户的表test3_05,删除表中的班级不规范的那些错误数据,不规范是指和大多数不一致。
这个题知识点是学会用sql找出不规范的数据,而不是用人工办法找不规范。

create table test3_05 as
select * from pub.student_31
where class not like ‘% %’ and class not like ‘%级%’;

3-6
将pub用户下的Student_31及数据复制到主用户的表test3_06,删除表中的错误数据,不规范的数据也被认为是那些错误数据。
(1)学号不全是数字;
(2)出生日期和年龄不一致的(年龄=2012-出生年份);
(3)姓名有空格的或者长度小于2个字的;函数length()返回字符串长度。
(4)性别有错误的(只能够是"男"、“女”、空值);
(5)院系名称有空格的、院系名称为空值的;
(6)院系名称小于3个字的;
(7)班级数据有错误的(需要先找到班级里面的错误)。
保留最后全部正确的数据。

create table test3_06 as
select * from pub.student_31
delete from test3_06 where not regexp_like(sid,’2{12}$’)

delete from test3_06 where age != 2012 - extract(year from birthday)
delete from test3_06 where length(name)<2 or name like ‘% %’
delete from test3_06 where sex != ‘男’ and sex != ‘女’ and sex is not null;
delete from test3_06 where dname is null or dname like ‘% %’;
delete from test3_06 where length(dname)< 3 ;
delete from test3_06 where not regexp_like(class,’3{4}$’)

3-7
将pub用户下的Student_course_32及数据复制到主用户的表test3_07,删除其中的错误数据,错误指如下情况:
学号在学生信息pub.student中不存在的;

create table test3_07 as
select *from pub.student_course_32
where sid in(select sid from pub.student)

3-8
将pub用户下的Student_course_32及数据复制到主用户的表test3_08,删除其中的错误数据,错误指如下情况:
课程号和教师编号在教师授课表pub.teacher_course中不同时存在的,即没有该教师教该课程

create table test3_08 as
select a.*
from pub.student_course_32 a,pub.teacher_course b
where a.cid = b.cid and a.tid = b.tid;

3-9
将pub用户下的Student_course_32及数据复制到主用户的表test3_09,删除其中的错误数据,错误指如下情况:
成绩数据有错误(需要先找到成绩里面的错误)。
这个题知识点是学会用sql找出错误数据,而不是用人工办法找错误数据。
提示:寻找不规范有很多解决思路,可以去对比大纲最后的提示。

create table test3_09 as
select *
from pub.student_course_32
where score between 0 and 100

3-10
将pub用户下的Student_course_32及数据复制到主用户的表test3_10,删除其中的错误数据,错误指如下情况:
(1) 学号在学生信息pub.student中不存在的;
(2) 课程号在课程信息pub.course中不存在的;
(3) 教师编号在教师信息pub.teacher中不存在的;
(4) 课程号和教师编号在教师授课表pub.teacher_course中不存在的;
(5) 成绩数据有错误(需要先找到成绩里面的错误)。
保留最后正确的数据。

create table test3_10 as
select * from pub.student_course_32;
delete from test3_10 where sid not in (select sid from pub.student)
delete from test3_10 where cid not in (select cid from pub.course)
delete from test3_10 where tid not in (select tid from pub.teacher)
delete from test3_10 where (tid,cid) not in ( select tid,cid from pub.TEACHER_COURSE )
delete from test3_10 where score not between 0 and 100;

4-1
将pub用户下表student_41及数据复制到主用户的表test4_01中,使用alter table语句为表增加列:“总成绩:sum_score”。
使用update语句,利用pub.student_course、pub.course,统计 “总成绩”;

create table test4_01 as
select * from pub.student_41
alter table test4_01 add sum_score int
update test4_01set sum_score=(select sum(score)
from pub.student_course awhere a.sid=test4_01.sid)

4-2
将pub用户下表student_41及数据复制到主用户的表test4_02中,使用alter table语句为表增加列"平均成绩:avg_score" (小数点后保留1位)。
利用pub.student_course、pub.course,统计"平均成绩",四舍五入到小数点后1位

create table test4_02 as
select * from pub.student_41
alter table test4_02 add avg_score numeric(3,1)
update test4_02set avg_score=(select avg(score)from pub.student_course awhere test4_02.sid=a.sid)

4-3
将pub用户下表student_41及数据复制到主用户的表test4_03中,使用alter table语句为表增加列:“总学分:sum_credit”。
使用update语句,利用pub.student_course、pub.course,统计 “总学分”;
这是需要注意:成绩及格才能够计算所得学分。

update test4_03set sum_credit=(select sum(credit)
from (
select sid ,cid ,max(score) score
from pub.student_course group by sid,cid) a natural join pub.course bwhere test4_03.sid=a.sid and score>=60)

4-4
将pub用户下表student_41及数据复制到主用户的表test4_04中。
根据列院系名称dname到pub.department找到对应院系编号did,将对应的院系编号回填到院系名称列dname中,如果表中没有对应的院系名称,则列dname中内容不变仍然是原来的内容。

update test4_04set dname=(select didfrom pub.department awhere a.dname=test4_04.dname )where test4_04.dname in(select dname from pub.department)

4-5
将pub用户下表student_41及数据复制到主用户的表test4_05中,使用alter
table语句为表增加4个列:“总成绩:sum_score”、
“平均成绩:avg_score”、“总学分:sum_credit”、"院系编号:did varchar(2) “。
(1) 利用pub.student_course、pub.course,统计 “总成绩”;
(2) 利用pub.student_course、pub.course,统计"平均成绩”,四舍五入到小数点后1位;
(3) 利用pub.student_course、pub.course,统计 “总学分”;
(4) 根据院系名称到pub.department或者pub.department_41中,找到对应编号,填写到院系编号中,如果都没有对应的院系,则填写为00

create table test4_05 as(select *from pub.STUDENT_41)
alter table test4_05 add sum_score int
alter table test4_05 add avg_score numeric(4,1)
alter table test4_05 add sum_credit intalter table test4_05 add did varchar(2)
update test4_05set sum_score=(select sum_score
from test4_01where test4_01.sid=test4_05.sid)
update test4_05set avg_score=(select avg_score
from test4_02where test4_02.sid=test4_05.sid)
update test4_05set sum_credit=(select sum_credit from test4_03where test4_03.sid=test4_05.sid)
update test4_05set did=(select didfrom pub.DEPARTMENT
where pub.DEPARTMENT.DNAME=test4_05.dname)
where dname in(select dname from pub.DEPARTMENT)
update test4_05set did=(select didfrom pub.DEPARTMENT_41where pub.DEPARTMENT_41.DNAME=test4_05.dname)where dname in(select dname from pub.DEPARTMENT_41)
update test4_05set did='00’where did is null

4-6
将pub用户下的Student_42及数据复制到主用户的表test4_06中,对表中的数据进行整理,修复那些不规范的数据:
剔除姓名列中的所有空格;

create table test4_06 as
select *from pub.student_42
update test4_06set name=translate(name,’/ ‘,’/’)

4-7
将pub用户下的Student_42及数据复制到主用户的表test4_07中,对表中的数据进行整理,修复那些不规范的数据:
对性别列进行规范(需要先确定哪些性别数据不规范,也就是那些和大多数不一样的就是不规范的);

update test4_07
set sex=translate(sex,’/性 ‘,’/’)

4-8
将pub用户下的Student_42及数据复制到主用户的表test4_08中,对表中的数据进行整理,修复那些不规范的数据:
对班级列进行规范(需要先确定哪些班级不规范)。

update test4_08
set class=translate(class,’/级 ‘,’/’)

4-9
将pub用户下的Student_42及数据复制到主用户的表test4_09中,对表中的数据进行整理,修复那些不规范的数据:
年龄为空值的根据出生日期设置学生年龄(截止到2012年的年龄,即年龄=2012-出生年份),年龄不为空值的不要改变。

update test4_09
set age=2012-extract(year from birthday)where age is null

4-10
将pub用户下的Student_42及数据复制到主用户的表test4_10中,对表中的数据进行整理,修复那些不规范的数据:
(1) 剔除姓名列中的所有空格;
(2) 剔除院系名称列中的所有空格;
(3) 对性别列进行规范(需要先确定哪些性别数据不规范,也就是那些和大多数不一样的就是不规范的);
(4) 对班级列进行规范(需要先确定哪些班级不规范)。
(5) 年龄为空值的根据出生日期设置学生年龄(截止到2012年的年龄,即年龄=2012-出生年份),年龄不为空值的不要改变

create table test4_10 as
(select *from pub.Student_42)
update test4_10set name=translate(name,’/ ‘,’/’)
update test4_10set dname=translate(dname,’/ ‘,’/’)
update test4_10set sex=translate(sex,’/性 ‘,’/’)
update test4_10set class=translate(class,’/级 ‘,’/’)
update test4_10set age=2012-extract(year from birthday)where age is null

5-1
在学生表pub.student中统计名字(姓名的第一位是姓氏,其余为名字,不考虑复姓)的使用的频率,将统计结果放入test5_01中,表结构如下。
First_name varchar(4) frequency numeric(4)

create table test5_01
(first_name varchar(4),
frequency numeric(4))
insert into test5_01
(first_name,frequency)
(select substr(name,2),count(*)
from pub.studentgroup by substr(name,2) )
//substr取内容第二个及以后

5-2
在学生表pub.student中统计名字(姓名的第一位是姓氏,不作统计,名字指姓名的第二个之后的汉字)的每个字使用的频率,将统计结果放入test5_02中(特别提示:需要区别union和union all的不同),表结构如下。

insert into test5_02
(letter,frequency)
select zi,count(*)
from((select substr(name,2,1) zi
from pub.student)
union all(select substr(name,3,1) zi
from pub.student))
where zi is not null
group by zi//最多只有三个字的名字

5-3
创建"学院班级学分达标情况统计表1"test5_03,依据pub.student, pub.course,pub.student_course统计形成表中各项数据,成绩>=60为及格计入学分,总学分>=10算作达标,院系为空值的数据不统计在下表中,表结构:院系名称dname、班级class、学分达标人数p_count1、学分未达标人数p_count2、总人数p_count。
Dname varchar(30) class varchar(10) P_count1 Int P_count2 int P_count int
计算机学院 2006
计算机学院 2007
软件学院 2006
create table test5_03(
dname varchar(30),
class varchar(10),
P_count1 int,
P_count2 int,
p_count int
)
P_count1,P_count2,dname,class,count(*)
create table test5_031 as
select
*
from
(select
dname,class,count(sid) P_count1
from
(select dname,class,sid,sum(credit) sum_credit from ((select sid,dname,class from pub.student where dname is not null) natural join
(select sid,cid,score from pub.student_course where score>=60) natural join pub.course) group by dname,class,sid)
where sum_credit>=10
group by dname,class
)

create table test5_032 as
insert into test5_032
select
dname,class,sum(p2) P_count2
from
((select
dname,class,count(sid) p2
from
(select dname,class,sid,sum(credit) sum_credit from ((select sid,dname,class from pub.student where dname is not null) natural join
(select sid,cid,score from pub.student_course where score>=60) natural join pub.course) group by dname,class,sid)
where sum_credit < 10
group by dname,class)
union all(
select
dname,class,count(sid) p2
from
pub.student
where
dname is not null and sid not in (select sid from pub.student_course)
group by dname,class
))
group by dname,class

create table test5_033 as
insert into test5_033
select
dname,class,count(sid) P_count
from
pub.student
where dname is not null
group by dname,class

insert into test5_03
select
*
from
test5_031 natural full outer join test5_032 natural full outer join test5_033

update test5_03
set
P_count1=0
where P_count1 is null

update test5_03
set
P_count2=0
where P_count2 is null
5-4
创建"学院班级学分达标情况统计表2"test5_04,依据pub.student, pub.course,pub.student_course统计形成表中各项数据,成绩>=60为及格计入学分,2008级及之前的班级总学分>=8算作达标,2008级之后的班级学分>=10算作达标,院系为空值的数据不统计在下表中,表结构:院系名称dname、班级class、学分达标人数p_count1、学分未达标人数p_count2、总人数p_count。
Dname varchar(30) class varchar(10) P_count1 int P_count2 int P_count int
计算机学院 2006
计算机学院 2007
软件学院 2006

create table test5_04(
dname varchar(30),
class varchar(10),
P_count1 int,
P_count2 int,
p_count int
)
create table test5_041 as
select
dname,class,sum(p1) P_count1
from
((select
dname,class,count(sid) p1
from
(select dname,class,sid,sum(credit) sum_credit from ((select sid,dname,class from pub.student where dname is not null) natural join
(select sid,cid,score from pub.student_course where score>=60) natural join pub.course) group by dname,class,sid)
where sum_credit>=8 and class<=2008
group by dname,class
)
union all(
select
dname,class,count(sid) p1
from
(select dname,class,sid,sum(credit) sum_credit from ((select sid,dname,class from pub.student where dname is not null) natural join
(select sid,cid,score from pub.student_course where score>=60) natural join pub.course) group by dname,class,sid)
where sum_credit>=10 and class>2008
group by dname,class
))
group by dname,class

create table test5_042 as
select
dname,class,sum(p2) P_count2
from
((select
dname,class,count(sid) p2
from
(select dname,class,sid,sum(credit) sum_credit from ((select sid,dname,class from pub.student where dname is not null) natural join
(select sid,cid,score from pub.student_course where score>=60) natural join pub.course) group by dname,class,sid)
where sum_credit < 8 and class<=2008
group by dname,class)
union all(
select
dname,class,count(sid) p2
from
(select dname,class,sid,sum(credit) sum_credit from ((select sid,dname,class from pub.student where dname is not null) natural join
(select sid,cid,score from pub.student_course where score>=60) natural join pub.course) group by dname,class,sid)
where sum_credit < 10 and class>2008
group by dname,class
)
union all(
select
dname,class,count(sid) p2
from
pub.student
where
dname is not null and sid not in (select sid from pub.student_course)
group by dname,class
)
)
group by dname,class

create table test5_043 as
select
dname,class,count(sid) P_count
from
pub.student
where dname is not null
group by dname,class

insert into test5_04
select
*
from
test5_041 natural full outer join test5_042 natural full outer join test5_043

update test5_04
set
P_count1=0
where P_count1 is null

update test5_04
set
P_count2=0
where P_count2 is null

5-5
注意事项:
如果一个学生一门课程有多次成绩,仅仅计算最高成绩,也就是只用他的最好成绩参加如下统计。
5. 查询各院系(不包括院系名称为空的)的数据结构平均成绩avg_ds_score、操作系统平均成绩avg_os_score,平均成绩四舍五入到个位,创建表test5_05,表结构及格式如下:
Dname Avg_ds_score Avg_os_score
马克思主义学院 72 70
软件学院 77 74
艺术学院 77 76
医学院 74 73

create table test5_051 as
select
dname,round(avg(Max_score)) avg_ds_score
from
pub.student natural join (select sid,cid,max(score) Max_score from pub.student_course where cid=300002 group by sid,cid)
where
dname is not null
group by dname

create table test5_052 as
select
dname,round(avg(Max_score)) avg_os_score
from
pub.student natural join (select sid,cid,max(score) Max_score from pub.student_course where cid=300005 group by sid,cid)
where
dname is not null
group by dname

create table test5_05 as
select *
from
test5_051 natural join test5_052

5-6
查询"计算机科学与技术学院"的同时选修了数据结构、操作系统两门课的学生的学号sid、姓名name、院系名称dname、数据结构成绩ds_score、操作系统成绩os_score,创建表test5_06,

create table test5_061 as
select
sid,name,dname,Max_score ds_score
from
pub.student natural join (select sid,cid,max(score) Max_score from pub.student_course group by sid,cid)
where
dname=‘计算机科学与技术学院’ and cid=300002

create table test5_062 as
select
sid,name,dname,Max_score os_score
from
pub.student natural join (select sid,cid,max(score) Max_score from pub.student_course group by sid,cid)
where
dname=‘计算机科学与技术学院’ and cid=300005

create table test5_06 as
select *
from
test5_061 natural join test5_062

5-7
查询计算机科学与技术学院的选修了数据结构或者操作系统的学生的学号sid、姓名name、院系名称dname、数据结构成绩ds_score、操作系统成绩os_score,创建表test5_07,表结构及格式如下:

create table test5_07 as
select *
from
test5_061 natural full outer join test5_062

5-8
查询计算机科学与技术学院所有学生的学号sid、姓名name、院系名称dname、数据结构成绩ds_score、操作系统成绩os_score,创建表test5_08,表结构及格式如下

create table test5_061 as
select
sid,name,dname,Max_score ds_score
from
pub.student natural join (select sid,cid,max(score) Max_score from pub.student_course group by sid,cid)
where
dname=‘计算机科学与技术学院’ and cid=300002

create table test5_062 as
select
sid,name,dname,Max_score os_score
from
pub.student natural join (select sid,cid,max(score) Max_score from pub.student_course group by sid,cid)
where
dname=‘计算机科学与技术学院’ and cid=300005

create table test5_082 as
insert into test5_082
select
sid,name,dname
from
pub.student
where
dname=‘计算机科学与技术学院’ and sid not in (select sid from pub.course natural join pub.student_course where cid=300002 or cid=300005)

create table test5_08 as
insert into test5_08
select distinct *
from
test5_061 natural full outer join test5_062 natural full outer join test5_082

6-1
例如:找出年龄小于20岁的所有学生的学号、姓名、年龄
正确执行:create view test6_00 as select sid,name,age from pub.student where age>20
Oracle扩展后方便写法:
create or replace view test6_00 as select sid,name,age from pub.student where age>20
直行select count(*) from test6_00 检查是否能够5分钟内查询出全部结果,如果超时说明可能有错误,这种情况下严禁执行"update dbtest set test=6"进行交卷。
找出年龄小于20岁且是"物理学院"的学生的学号、姓名、院系名称,按学号排序。

create or replace view test6_01as select sid,name,age,dnamefrom pub.studentwhere age<20 and dname='物理学院’order by sid

6-2
查询统计2009级、软件学院每个学生的学号、姓名、总成绩(列名sum_score)(如果有学生没有选一门课,则总成绩为空值)。

create or replace view test6_02as
select sid,name,sum(score) sum_score
from pub.student natural join pub.student_course
where class=2009 and dname='软件学院’group by sid,name

6-3
查询2010级、计算机科学与技术学院、操作系统的学生成绩表,内容有学号、姓名、成绩。

create or replace view test6_03
as select sid,name,score
from pub.student natural full outer join pub.student_course
where class=2010 and dname=‘计算机科学与技术学院’ and cid=300005

6-4
找出选修"数据库系统"课程,且成绩大于90的学生的学号、姓名

create or replace view test6_04as select sid,name
from pub.student natural join pub.student_course
where score>90 and cid=300003

6-5
找出姓名叫"李龙"的学生的学号及其选修全部课程的课程号、课程名和成绩。

create or replace view test6_05 as
select a.sid,b.cid,b.name,score
from (select sid,cid,score from pub.student_course
where sid in (select sid from pub.student where name=‘李龙’) ) a join pub.course b on a.cid = b.cid;

6-6
找出选修了所有课程的学生的学号、姓名

create or replace view test6_06 as
select sid,namefrom pub.student a
where sid not in(select sid from pub.student,pub.course where (sid,cid) not in (select sid,cid from pub.student_course));

6-7
找出选修了所有课程并且所有课程全部通过的学生的学号、姓名

create or replace view test6_07 as
select sid,namefrom pub.student natural join pub.student_course
where sid not in (select sid from pub.student,pub.course where (sid,cid) not in (select sid,cid from pub.student_course))and sid not in(select sid from pub.student_course where score<60);

6-8
检索先行课的学分为2的课程号、课程名。

create or replace view test6_08 as
select cid,name from pub.course where
fcid in(select cid from pub.course where credit=2);

6-9
查询统计2010级、化学与化工学院的学生总学分表,内容有学号、姓名、总学分sum_credit。

create or replace view test6_09 as
select b.sid,b.name,a.sum_credit from
(select sid,sum(credit) sum_credit from
((select * from pub.student_course where score>=60) x join (select * from pub.course) yon x.cid=y.cid)where sid in
(select sid from pub.student where class=‘2010’ and dname=‘化学与化工学院’) group by sid) a join (select sid,name from pub.student) b on a.sid = b.sid;

6-10
找出有间接先行课的所有课程的课程号、课程名称。

create or replace view test6_10 as
select cid,name
from pub.course
where fcid in(select cid from pub.course where fcid is not null);

7-1

1. 将pub用户下表student的3个列sid,name,birthday复制到表test7_01中。
2. 执行如下查询,观察运行速度(5秒以上)。
查询Samefirstname相同姓氏的人数。
select * from
(select sid,name,birthday,
(select count(*) from test7_01 where substr(name,1,1)=substr(t1.name,1,1)) samefirstname
from pub.student_testindex t1)
where samefirstname=7
3. 为test7_01创建一个仅仅一个索引,保证上面SQL耗时在1秒内。
4. 交卷验证

create index test10_01_name on test10_01 (substr(name,1,1))

7-2
1. 将pub用户下表student的3个列sid,name,birthday复制到表test7_02中。
2. 将出生日期全部修改成一天:
Update test7_02 set birthday=to_date(‘19881018’,‘yyyymmdd’) where substr(sid,12,1)=‘0’;
3. 为test7_02创建一个仅仅一个索引,保证下面SQL耗时在1秒内。
Samenamebirthday同名同生日的人数,Samebirthday相同出生日期的人数
select * from
(select sid,name,birthday,
(select count() from test7_02 where name=t1.name and birthday=t1.birthday) samenamebirthday,
(select count(
) from test7_02 where birthday=t1.birthday) samebirthday
from pub.student_testindex t1)
where samebirthday=403
4. 交卷验证
5. 思考题,test7_02不增建索引情况下,下面这个查询能使用索引吗?改进后能使用索引吗?
select * from
(select sid,name,birthday,
(select count(*) from test7_02 where name=t1.name) samename
from pub.student t1)
where samename=7

create index test7_02_name on test7_02 (birthday,name)

7-3
1. pub用户下表student已经用下面两句SQL创建了两索引。
Create index student_birthday on student(birthday);
Create index student_name on student(name);
2. 下面SQL不能用索引耗时超过2秒,在逻辑不变情况下,修改SQL中标为记红色的子查询的where条件部分,不要修改其它地方,使其能使用索引。
说明:因为pub.student_testindex数据行数太少,不能通过修改主句where绕过问题。
查询samefirstname同姓氏的人数。
select * from
(select sid,name,birthday,
(select count(*) from pub.student
where substr(name,1,1)=substr(t1.name,1,1)
) samefirstname
from pub.student_testindex t1) where samefirstname=7
3. 修改以后验证耗时在2秒之内,将修改以后语句创建成视图create view test7_03 as select ……。
4. 交卷验证

create or replace view test7_03 as
select * from(select sid,name,birthday,(select count(name) from pub.student where name like concat(substr(t1.name,1,1),’%’)) samefirstnamefrom pub.student_testindex t1)where samefirstname=7

7-4
1. pub用户下表student已经用下面两句SQL创建了两索引。
Create index student_birthday on student(birthday);
Create index student_name on student(name);
2. 下面SQL不能用索引耗时超过1秒,在逻辑不变情况下,修改SQL中标为记红色的子查询的where条件部分,不要修改其它地方,使其能使用索引。
说明:因为pub.student_testindex数据行数太少,不能通过修改主句where绕过问题。
select * from
(select sid,name,birthday,
(select count() from pub.student
where to_char(birthday,‘yyyymm’)=to_char(t1.birthday,‘yyyymm’)
) sameyearmonth,
(select count(
) from pub.student
where extract (year from birthday) =extract (year from t1.birthday)
) sameyear
from pub.student_testindex t1) where sameyearmonth=35
3. 修改以后验证耗时在1秒之内,将修改以后语句创建成视图create view test7_04 as select ……。
4. 交卷验证

create or replace view test7_04 as
select * from
(select sid,name,birthday,
(select count() from pub.student
where birthday >= trunc(t1.birthday,‘mm’) and birthday<=last_day(t1.birthday) ) sameyearmonth,
(select count(
) from pub.student
where birthday >= trunc(t1.birthday,‘yyyy’) and birthday<=last_day(add_months(trunc(t1.birthday,‘y’),11)) ) sameyear
from pub.student_testindex t1) where sameyearmonth=35

7-5
1. pub用户下表student已经用下面两句SQL创建了两索引。
Create index student_birthday on student(birthday);
Create index student_name on student(name);
2. 下面SQL不能用索引耗时超过1秒,在逻辑不变情况下,修改SQL中标为记红色的子查询的where条件部分,不要修改其它地方,使其能使用索引。
说明:因为pub.student_testindex数据行数太少,不能通过修改主句where绕过问题。
查询nextbirthday晚一天出生的人数
select * from
(select sid,name,birthday,
(select count(*) from pub.student
where birthday-1=t1.birthday
) nextbirthday
from pub.student_testindex t1) where nextbirthday=7
3. 修改以后验证耗时在1秒之内,将修改以后语句创建成视图create view test7_05 as select ……。
4. 交卷验证

create or replace view test7_05 as
select * from
(select sid,name,birthday,
(select count(*) from pub.student
where birthday=t1.birthday+1
) nextbirthday
from pub.student_testindex t1) where nextbirthday=7

8-1
数据修改的提交和回退、实体授权
一、 实验内容
启动两个不同浏览器,firefox登录主账号userID、360浏览器登录备用账号userbID,测试提交和回退的作用,了解锁等待、授权知识。
二、 实验步骤
1. 使用主用户userID登入数据库,简称主窗口。
2. 使用备用用户userbID登入数据库,简称备用窗口。
3. 关闭自动提交复选框。
4. 主用户访问备用用户的表之前,需要在备用账号中将相应的表的相应的权限授权给主用户,这样主用户才可以查询操作备用用户的相应的表。
在主用户下可以执行select * from userbId.test8_00查询备用用户的表test8_00的数据,如果没有授权,则会提示表没有表找到。
如果备用用户执行grant select on test8_00 to userID,即授权表test8_00的select权限给用户userID,上面的查询语句就可以正确执行,并查询到相应的结果。
5. 常用的授权、命令:
grant select on test8_00 to userID授权表test8_00的select权限给用户userID。
grant update on test8_00 to userID授权表test8_00的update权限给用户userID。
grant insert on test8_00 to userID授权表test8_00的insert权限给用户userID。
grant delete on test8_00 to userID授权表test8_00的delete权限给用户userID。
grant all on test8_00 to userID授权表test8_00的all权限给用户userID。
revoke select on test8_00 from userID收回表test8_00的insert权限从用户userID。
6. 在备用用户下将pub.teacher复制到test8_00中,然后将其所有权限给主用户。
7. 按表中序号在相应窗口执行对应的命令(主用户访问备用用户表需要授权)。
表格详见《数据库系统实验大纲》
8.

假设数据中有张老师,通过上面的操作以后,他在每次查询的时候的年龄是多少?根据你的判断得出结果,然后按步骤进行实验验证,在主用户下创建一个表test8_10(test varchar(20),age numeric (3)),插入10行数据,分表存放10个结果。

create table teat8_10(test varchar(20),age numeric (3))
insert into test8_10 (test,age) values(‘结果1’,88)
insert into test8_10 (test,age) values(‘结果2’,90)
insert into test8_10 (test,age) values(‘结果3’,90)
insert into test8_10 (test,age) values(‘结果4’,76)
insert into test8_10 (test,age) values(‘结果5’,90)
insert into test8_10 (test,age) values(‘结果6’,90)
insert into test8_10 (test,age) values(‘结果7’,86)
insert into test8_10 (test,age) values(‘结果8’,86)
insert into test8_10 (test,age) values(‘结果9’,76)
insert into test8_10 (test,age) values(‘结果10’,86)

9-1
1.创建表test9_01,表的结构同pub.student_11_1一样。
2.为test9_01的sid创建唯一不重复索引。
3.将pub用户下的Student中性别是“女”的数据添加到test9_01中。
4.将pub用户下的Student_11_1中性别是“女”的数据添加到test9_01中,如果某个学号已经包含在test9_01中,这个记录就不要再插入了(即不要插入重复学号的数据)。
5.将pub用户下的Student_11_2中性别是“女”的数据添加到test9_01中,如果某个学号已经包含在test9_01中,这个记录就不要再插入了(即不要插入重复学号的数据)。
6.要求完成上述功能,请采用1条create table、1条create index、3条insert共5条SQL方式完成。

create table test9_01(
sid char(12) not null unique,
name varchar2(10) not null,
sex char(2), age int, birthday date,
dname varchar2(30), class varchar2(10) );
insert into test9_01 select * from pub.student where sex=‘女’;
insert into test9_01 select * from pub.student_11_1 where sex=‘女’ and sid not in (select sid from test9_01);
insert into test9_01 select * from pub.student_11_2 where sex=‘女’ and sid not in (select sid from test9_01);

9-2
.创建表test9_02,表的结构同pub.student_11_1一样。
8.为test9_02的sid创建唯一不重复索引。
9.将pub用户下的Student中性别是“女”的且pub.student_course中存在不及格成绩的同学添加到test9_02中。
10.将pub用户下的Student_11_1中性别是“女”的且pub.student_course中存在不及格成绩的同学数据添加到test9_02中,如果某个学号已经包含在test9_02中,这个记录就不要再插入了(即不要插入重复学号的数据)。
11.将pub用户下的Student_11_2中性别是“女”的且pub.student_course中存在不及格成绩的同学数据添加到test9_02中,如果某个学号已经包含在test9_02中,这个记录就不要再插入了(即不要插入重复学号的数据)。
12.要求完成上述功能,请采用1条create table、1条create index、3条insert共5条SQL方式完成。

create table test9_02(
sid char(12) not null unique,
name varchar2(10) not null,
sex char(2), age int,
birthday date,
dname varchar2(30),
class varchar2(10) );
insert into test9_02 select * from pub.student where sex=‘女’ and sid in(select sid from pub.student_course where score < 60);
insert into test9_02 select * from pub.student_11_1 where sex=‘女’ and sid in (select sid from pub.student_course where score < 60) and sid not in (select sid from test9_02);
insert into test9_02 select * from pub.student_11_2 where sex=‘女’ and sid in (select sid from pub.student_course where score < 60) and sid not in (select sid from test9_02);


  1. [:digit:] ↩︎

  2. [:digit:] ↩︎

  3. [:digit:] ↩︎

山东大学数据库实验一、二、三、四、五、六、七、八、九答案(大集合)相关推荐

  1. 孙立岩 python-basic: 用于学习python基础的课件(五六七八九十)

    五.数字(Number) 数字类型 python中数字有四种类型:整数.布尔型.浮点数和复数. int (整数), 如 1, 只有一种整数类型 int,并没有其他语言中的byte,short,long ...

  2. mysql实验报告2_数据库实验报告二

    <数据库实验报告二>由会员分享,可在线阅读,更多相关<数据库实验报告二(24页珍藏版)>请在人人文库网上搜索. 1.XIAN TECHNOLOGICAL UNIVERSITY ...

  3. 【五六七人口普查】我国省市两级各行业门类人口及三次产业人口比重

    人口数据是我们在各项研究中最常使用的数据!之前我们分享过第七次人口普查(简称七普)的数据!很多小伙伴拿到数据后都反馈数据非常好用,同时很多小伙伴咨询有没有前面几次人口普查的数据,这样方便做人口变化分析 ...

  4. 【五六七人口普查】省市两级人口受教育情况

    人口数据是我们在各项研究中最常使用的数据!之前我们分享过第七次人口普查(简称七普)的数据!很多小伙伴拿到数据后都反馈数据非常好用,同时很多小伙伴咨询有没有前面几次人口普查的数据,这样方便做人口变化分析 ...

  5. 【五六七人口普查】我国区县级人口基本情况

    人口数据是我们在各项研究中最常使用的数据!之前我们介绍过基于第五六七次人口普查整理的全国省市两级的人口基本情况(可查看之前推送的文章),本次我们向大家介绍基于第五六七次人口普查整理的区县级人口基本情况 ...

  6. 【五六七人口普查】我国省市两级人口基本情况

    人口数据常用于各项研究中!之前我们介绍过第七次人口普查(简称七普)的人口数据!很多小伙伴咨询有没有前面几次人口普查指标数据的介绍,这样方便做人口变化分析!本次我们特地整理了五普.六普的人口数据指标,加 ...

  7. 【五六七人口普查】省市两级有老年人的户数、人口自然变动和迁入人口

    人口数据常用于各项研究中!之前我们介绍过第七次人口普查(简称七普)的人口数据!很多小伙伴咨询有没有前面几次人口普查指标数据的介绍,这样方便做人口变化分析!本次我们特地整理了五普.六普的人口数据指标,加 ...

  8. 【五六七人口普查】省市两级分年龄、性别的人口

    人口数据常用于各项研究中!之前我们介绍过第七次人口普查(简称七普)的人口数据!很多小伙伴咨询有没有前面几次人口普查指标数据的介绍,这样方便做人口变化分析!本次我们特地整理了五普.六普的人口数据指标,加 ...

  9. 【五六七人口普查】我国省市两级人口婚姻状况和妇女生育状况

    人口数据是我们在各项研究中最常使用的数据!之前我们分享过第七次人口普查(简称七普)的数据!很多小伙伴拿到数据后都反馈数据非常好用,同时很多小伙伴咨询有没有前面几次人口普查的数据,这样方便做人口变化分析 ...

  10. 【五六七人口普查】我国省市两级家庭户住房状况

    人口数据是我们在各项研究中最常使用的数据!之前我们分享过第七次人口普查(简称七普)的数据!很多小伙伴拿到数据后都反馈数据非常好用,同时很多小伙伴咨询有没有前面几次人口普查的数据,这样方便做人口变化分析 ...

最新文章

  1. Oracle事务处理—隔离级别
  2. python的socket编程_Python Socket编程详细介绍
  3. python利器下载-Python打包利器:auto-py-to-exe
  4. 工作随笔0828:领导离职前对我的忠告
  5. Johnny and Another Rating Drop CodeForces - 1362C(规律)
  6. ckeditor+ckfinder+syntaxhighlighter编辑器
  7. 容器服务Windows Kubernetes使用阿里云日志服务来收集容器日志
  8. xposed hook 静态函数_开源Hook框架-epic-实现浅析
  9. 微信「扫码支付」被诉侵犯专利权;苹果回应“iOS 13 频繁提醒 App 定位”;Python 2 退休 | 极客头条...
  10. 0831 - 每晚放松一刻
  11. R 语言基本操作(基本信息的查看、与本地文件系统交互、编译器版本升级)
  12. 搜集整理一些Cron表达式例子
  13. 计算机网络经典试题答案,2016年计算机软考网络工程师经典练习试题及答案
  14. java中移动光标怎么写_java 程序当中无法做到光标跟随
  15. 关于获取日周月的时间处理与日期联动处理
  16. 智能驾驶大数据是什么?传统车企如何升级?
  17. Linux内核2:中断代码分析
  18. python为什么运行不了_python为什么安装了运行不了?
  19. 电脑没声音 小喇叭不见了怎么办
  20. hdu 5238 Calculator(线段树+CRT)

热门文章

  1. 超级硬核!Java 自学路线总结,已 Get 大厂 Offer,建议立马收藏!
  2. Web 架构师的能力 转载之程序员官方blog
  3. iOS 底层探索篇 —— KVC 底层原理
  4. 拼多多新手商家怎么定价?
  5. 后代选择器与子元素选择器
  6. 车载综合信息平台方案
  7. RDMA技术详解——DMA和RDMA概念
  8. Hackbar初步了解和火狐中安装
  9. dw网页设计期末设计一个网页_Dw网页设计制作九个小技巧,你都会吗?
  10. 艾美捷焦磷酸(PPi)分析试剂盒,高通量筛选神器