| 文章目录 零、前言 本文所有操作均在Oracle数据库下运行,在某些地方的语法可能与MySQL不同。 另外,是否区分大小写也有不同。(参看此文:MySQL与Oracle的大小写问题) 本文下篇:数据库基本操作总结(下)【数据控制、安全性和完整性】 SQL语言集数据定义、数据操纵、数据查询、数据控制功能于一体。 数据定义:create,drop,alter 数据操纵:增(insert into … ),删(delete from …),改(update … set …) 数据查询:select 数据控制:grant(授予权限),revoke(收回权限) 一、数据定义(create,alter,drop) 1.建立基本表 创建教材中的学生表(Student)、学生选课表(SC)、课程表(Course) (1)学生表:Student (Sno,Sname,Sage,Ssex,Sdept),其中学号Sno为主码。 create table Student
(
    Sno number primary key,
    Sname varchar2(10),
    Sage int,
    Ssex char(2),
    Sdept varchar2(10)
);
 (2)课程表:Course (Cno, Cname, Cpno, Ccredit)其中课程号Cno主码;先行课为外码参照Course表中Cno字段。 create table Course
(
    Cno number primary key,
    Cname varchar2(10),
    Cpno varchar2(10) references Course(Cno),
    Ccredit int
);
 (3)学生选课表:SC(Sno, Cno, Grade)其中学号Sno、课程号Cno为主码;Sno为外码参照Student表中Sno字段;Cno为外码参照Course表中Cno字段。 create table SC
(
    Sno number references Student(Sno),
    Cno number references Course(Cno),
    Grade int,
    primary key (Sno,Cno)
);
 2.修改基本表 (1)在Student表中加入属性BloodType【char(2)型】。 alter table Student add BloodType char(2);
 (2)修改表Student中的Sdept属性的数据类型为varchar2(40),注意和定义表的时候类型不同。 alter table Student modify Sdept varchar2(40);
 (3)给表Student的sage列添加一个自定义约束,sage必须大于15且小于30。 alter table Student add constraint age_ck check(Sage>15 and Sage<30);
 (4)删除(3)中新添加的约束。 alter table Student drop constraint age_ck;
 (5)SC表中的sno增加外键约束f_sno,参照Student表中的sno字段。 alter table sc add constraint f_sno foreign key (sno) references student(sno);
 (6)删除表Student中的字段BloodType。 alter table Student drop (BloodType);   
 3.删除基本表 (1)删除基本表Student。 drop table Student;
 (2)删除基本表SC。 drop table SC;
 4.索引操作 (1)在SC表上建立关于Sno升序、Cno降序的唯一索引i_sc+学号后四位。 create unique index i_sc on SC(Sno asc,Cno desc,substr(Sno,-4));
 (2)删除Course表上的索引i_sc。 drop index i_sc;
 二、数据操纵(insert,update,delete) 1.插入数据 1)向Student表中插入数据 2)向Course表中插入数据 3)向SC表中插入数据 可参考如下数据,也可不参考。 
 insert into STUDENT(SNO,SNAME,SSEX,SAGE,SDEPT) values(200215121,'李勇','男',20,'CS');
insert into STUDENT(SNO,SNAME,SSEX,SAGE,SDEPT) values(200215122,'刘晨','女',19,'CS');
insert into STUDENT(SNO,SNAME,SSEX,SAGE,SDEPT) values(200215123,'王敏','女',18,'MA');
insert into STUDENT(SNO,SNAME,SSEX,SAGE,SDEPT) values(200215125,'张立','男',19,'IS');
insert into COURSE(CNO,CNAME,CPNO,CCREDIT) values(1,'数据库',5,4);
insert into COURSE(CNO,CNAME,CPNO,CCREDIT) values(2,'数学',null,2);
insert into COURSE(CNO,CNAME,CPNO,CCREDIT) values(3,'信息系统',1,4);
insert into COURSE(CNO,CNAME,CPNO,CCREDIT) values(4,'操作系统',6,3);
insert into COURSE(CNO,CNAME,CPNO,CCREDIT) values(5,'数据结构',7,4);
insert into COURSE(CNO,CNAME,CPNO,CCREDIT) values(6,'数据处理',null,2);
insert into COURSE(CNO,CNAME,CPNO,CCREDIT) values(7,'PASCAL语言',6,4);
insert into SC(SNO,CNO,GRADE) values(200215121,1,92);
insert into SC(SNO,CNO,GRADE) values(200215121,2,85);
insert into SC(SNO,CNO,GRADE) values(200215121,3,88);
insert into SC(SNO,CNO,GRADE) values(200215122,4,90);
insert into SC(SNO,CNO,GRADE) values(200215122,3,80);
 2.修改数据 1)将王敏的同学的年龄改为20。 update STUDENT set sage=20 where sname='王敏';
 2)将全部同学的年龄加1。 update STUDENT set sage=sage+1;
 3)将’CS’系同学的选课信息中的成绩置0。 update SC set grade=0 where sno in 
(
    select sc.sno from STUDENT join SC on(student.sno=sc.sno)
    where sdept='CS'
);
 3.删除数据 1)删除和’刘晨’在同一个系的学生的信息。(包括刘晨自己也会被删除) delete from STUDENT where sdept in
(
    select sdept from STUDENT
    where sname='刘晨'
);
 然后发现删除不了,因为有外键约束,SC表依赖当前表的SNO, 所以要先删掉SC表中SNO的外键约束alter table sc drop constraint SYS_C0051208; 再执行删除语句即可。 2)删除’CS’系同学的选课信息。 delete from SC where sno in
(
    select sno from STUDENT
    where sdept='CS'
);
 三、数据查询(select) 1.包括排序、分组的单表查询 (1)求数学系学生的学号和姓名。 select sno,sname from student where sdept='MA';
 (2)求选修了课程的学生学号。 
select distinct sno from sc; 
 (3)求选修课程号为‘2’的学生号和成绩,并要求对查询结果按成绩的降序排列,如果成绩相同按学号的升序排列。 select sno,grade from sc where cno=2 order by grade DESC,sno ASC;
 (4)求选修课程号为’2’且成绩在80~90之间的学生学号和成绩,并将成绩乘以0.8输出。 select sno,grade*0.8 from sc where cno=2 and grade>=80 and grade<=90;
 (5)求数学系或计算机系姓张的学生的信息。 
select * from student where sname like '张%' and (sdept='MA' or sdept='CS');
 (6)求缺少了成绩的学生的学号和课程号。 select sno,cno from sc where grade is null;
 (7)查询各个课程号与相应的选课人数。 select cno,count(*) from sc group by cno;
 2.多表连接查询 (1)查询每个学生的情况以及他所选修的课程。 select student.sno,sname,ssex,sdept,cno from student,sc where student.sno=sc.sno;
 (2)求学生的学号、姓名、选修的课程及成绩。 select student.sno,sname,cno,grade from student,sc where student.sno=sc.sno;
 (3)求选修课程号为‘1’且成绩在90分以上的学生学号、姓名和成绩。 select student.sno,sname,grade from student,sc where student.sno=sc.sno and cno=1 and grade>=90;
 (4)查询每一门课程的间接先行课。 select c1.cno,c2.cpno from course c1,course c2 where c1.cpno=s2.cno;
 (5)查询与’刘晨’在同一个系学习的学生。 select s1.sno,s1.sname,s1.sage,s1.ssex,s1.sdept 
from student s1,student s2 
where s1.sdept=s2.sdept and s2.sname='刘晨'; 
 (6)查询选修了课程名为‘信息系统‘的学生学号和姓名。 select sc.sno,sname from student,sc,course 
where student.sno=sc.sno and sc.cno=course.cno and cname='信息系统'; 
 (7)查询平均成绩在80分以上的学生学号和平均成绩。 select sno,avg(grade) from sc group by sno having avg(grade)>=80;
 (8)查询选修了1门以上课程的学生的学号。 select sno from sc group by sno having count(*)>1;
 3.嵌套查询 (1)求选修了信息系统的学号和姓名。 select sno,sname from student where sno in
(
    select sno from sc where cno in 
    (
        select cno from course 
        where cname='信息系统'
    )
);
 (2)查询与刘晨在同一个系学习的学生。 select * from student where sdept in
(
	select sdept from student 
	where sname='刘晨'
);
 (3)求选修1号课程的成绩高于刘晨的成绩(指刘晨选修的所有的课程的成绩)的学生学号及成绩。 select sno,grade from sc where cno=1 and grade >
(
    select max(grade) from sc where sno in
    (
        select sno from student
        where sname='刘晨'
    )
);
 (4)求其他系中比计算机系某一学生年龄小的学生(即年龄小于计算机系年龄最大者的学生)。 select * from student where sage <
(
    select max(sage) from student 
    where sdept='CS'
);
 (5)求其他系中比计算机系学生年龄都小的学生姓名及年龄。 select sname,sage from student where sage <
(
    select min(sage) from student 
    where sdept='CS'
);
 (6)求选修课程超过2门的学生的学号和姓名。 select sno,sname from student where sno in
(
    select sno from sc
    group by sno having count(*)>2
);
 (7)求没有选修3号课程的学生姓名。 select sname from student where not exists 
(
    select * from sc
    where cno=3 and student.sno=sc.sno
);
 (8)查询选修了全部课程的学生姓名。【重点!】 select sname from student where not exists 
(
    select * from course where not exists
    (
        select * from sc
        where sc.cno=course.cno and sc.sno=student.sno
    )
);
 分析: 这个比较难懂,我们先看看内两层查询,表示选出当前学号(比如说122)没选的课 select * from course where not exists
(
    select * from sc
    where sc.cno=course.cno and sc.sno=200215122
); 
 如果这个结果是空,表示当前学号(比如说122)没选的课为空,最外层加一个select sname from student where not exists,表示选出所有 没有没选的课 的学生。 可以将not exists当作“减法”理解,内两层的意思就是把所有的课减去122学号选的课,如果为空(所有的课被122选的课给减没了),那么就选出122来。 (9)求至少选修了学号为“200215121”的学生所选修全部课程的学生学号和姓名。【重点!】 分析: 先选出121学生选的课 减去 122学生选的课: select * from sc sc1 where sno=200215121 and not exists
(
    select * from sc sc2
    where sc1.cno=sc2.cno and sc2.sno=200215122
);
 单纯的只有where not exist表示选出空的。 以上的整个式子表示减法:最内层用cno连接,表示找选课记录,然后121选课集合减去122选课集合。 过程的话实际就是两层for循环遍历,for(i: 121选课){for (j: 122选课)},对于每个i,判断122选课中是否存在j满足i.cno=j.cno,如果有,不为空,那么not exists就不选出这个i,实际上这不就相当于当前遍历到的i的记录被相同的j减去了吗!而且外层循环是121选课,说明最终输出的答案只能是121选课的子集,只要答案为空我们就把他选出来! 如果为空,说明122这个学号把121的所有课都选了(所以121的课被减没了)。 还有一种情况,就是122这个学号不仅把121的所有课都选了,他还选了其他课,这个时候的减法结果不是按“负数”理解,就理解成122把121的所有课都减没了,他还剩了多余的课,那是122的选课集合剩了(不是121剩了),最主要的是121被减没了,所以121的选课集合答案是空。 绕了这么多,反正核心就是: 找一个学生的选课集合作为“减数”,如果他大于等于121的选课集合,那么121的选课集合减去他之后就能变成空,这个“减数”就是我们要找的。 最后,把学号122改成变量,加一个最外层查询遍历所有学生, 因为找到为空的就要把他选出来,所以最外层写not exists选出空的数据库查询操作,那么整个答案就是: select sno,sname from student where not exists
(
    select * from sc sc1 where sno=200215121 and not exists
    (
        select * from sc sc2
        where sc1.cno=sc2.cno and sc2.sno=student.sno
    )
);
 (编辑:源码网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |