1.oracle增删改查会用到的关键字和函数
(1) * 代表所有,查询的时候会经常用到 比如我们查询一个表所有的信息就可以用了,当然也可以用表名.*,这个主要是多表连查的时候用
(2) AS 这个是用于给列起别名的时候,或是新建表的时候,例如:
select emp.ename as 姓名 from emp;
create table s1 as select emp.ename as 姓名 from emp;//这两个as起到不同的作用,第一个用于建表,第二个是起别名
(3) and and是并且的意思就是要同时满足,and经常用早where后面,当有多个条件的时候需要同时满足的时候用and链接
(4) or or 和and正好相反,or 只需要满足其中的一个 即可,多用于条件在一个范围内或是几个选项中即可的时候
(5) like like本身意思是像....,在这里他用于模糊查询,like经常和%,_,一起使用, %表示任意长字符,_表示一个字符,他们三个联合使用多余查询姓名和符合条件的其他数据
(6) desc (descend)是降序,asc (ascend)是升序,和order by 一起使用,而order by用到语句的结尾
(7) in in是在的意思,in多用于where后面,表示一个列或是一个字段在下面的条件里,比如 ename in('呵呵','哈哈');就是ename的取值要在呵呵和哈哈这两个里取,当然()还可以是查询语句就是子查询
(8) not in 和in是相对的就是不在的意思,这里不用多说了吧
(9) is not null 从字面意思也可以知道是不为空,我们查询数据的时候好多会用到这个,查询的数据如果为空就不显示就可以给个条件is not null
(10) case 字句,这个是用于我们查询的数据需要让他显示不同的名称的时候,就是需要转换显示的时候用.
2.增伤改查的实例
1:建表插入数据:
1、创建名 表空间mydata,建立用户st 使用mydata表空间,密码为st11
实验目的:
通过上机实验利用图形界面的方法创建数据库和基本表,并验证单表查询操作,为今后操作打下基础。
2、实验内容:
在st账户中,用sql语句建立下列关系表。
Student表
列名 说明 数据类型 约束
Sno 学号 普通编码定长字符串,长度为7 主键
Sname 姓名 普通编码定长字符串,长度为10 非空
Ssex 性别 普通编码定长字符串,长度为2 取值范围:{男,女}
Sage 年龄 整形
Dept 所在系 普通编码定长字符串,长度为20
Course表
列名 说明 数据类型 约束
Cno 课程号 普通编码定长字符串,长度为10 主键
Cname 课程名 普通编码定长字符串,长度为20 非空
Credit 学分 整型 大于0
Semester 开课学期 整型
SC表
列名 说明 数据类型 约束
Sno 学号 普通编码定长字符串,长度为7 主键,引用Student表的外键
Cno 课程号 普通编码定长字符串,长度为10 主键,引用Course表的外键
Grade 成绩 整型 取值范围:0-100
3、向已创建的二维表输入数据。
Student表数据
Sno Sname SSex Sage Dept
0811101 李勇 男 21 计算机系
0811102 刘晨 男 20 计算机系
0811103 王敏 女 20 计算机系
0811104 张小红 女 19 计算机系
0821101 张立 男 20 信息管理系
0821102 吴宾 女 19 信息管理系
0821103 张海 男 20 信息管理系
0831101 钱小平 女 21 通信工程系
0831102 王大力 男 20 通信工程系
0831103 张姗姗 女 19 通信工程系
Course表数据
Cno Cname Credit Semester
C001 高等数学 4 1
C002 大学英语 3 1
C003 大学英语 3 2
C004 计算机文化学 2 2
C005 Java 2 3
C006 数据库基础 4 5
C007 数据结构 4 4
C008 计算机网络 4 4
SC表数据
Sno Cno grade
0811101 C001 96
0811101 C002 80
0811101 C003 84
0811101 C005 62
0811102 C001 92
0811102 C002 90
0811102 C004 84
0811102 C006 76
0811102 C003 85
0811102 C005 73
0811102 C007 Null
0811103 C001 50
0811103 C004 80
0831101 C001 50
0831101 C004 80
0831102 C007 Null
0831103 C004 78
0831103 C005 65
0831103 C007 Null
实例讲解:
select 列名,列名 //要显示数据的列 * 所有列
from 数据源 //数据的来源
where 条件 //筛选符合条件的数据
group by 列名 // 将数据根据指定列进行分组
having 条件 // 分组后,筛选符合条件的数据
orderby 列名 [asc|desc] // 根据执行的列进行排序,asc升序 desc降序
1、st账户在中,完成以下多表连接查询的操作。
感觉有点难理解的都加注释了
(1)查询计算机系学生的修课情况,要求列出学生的名字、所修课的课程号和成绩。
/*这里没什么说的*/
select student.sname,course.cno,sc.grade
from student,course,sc
where sc.sno = student.sno
and sc.cno = course.cno
and dept='计算机系';
select Student.Sname,SC.Cno,SC.Grade from Student inner join SC on Student.Sno=SC.Sno
where Student.Dept='计算机系'
select s.sname,sc.grade from Student s left join SC sc on s.sno=sc.sno
where s.dept='计算机系'
(2)查询“信息管理系”修了“计算机文化学” 的学生姓名和成绩。
/*记得这里要给两个条件用到上面说的and*/
select sname,grade
from student,course,sc
where sc.sno = student.sno
and sc.cno = course.cno
and dept='信息管理系'
and cname='计算机文化学';
select s.sname,sc.grade from Student s left join SC sc on s.sno=sc.sno left join Course c on sc.cno=c.cno
where c.cname='计算机文化学' and S.dept='信息管理系'
(3)查询所有选修了Java课程的学生情况,列出学生姓名和所在系。
/*这种方法用到内连接,内连接可以好几个表连接,不只是两个表,每次把前面的表看成一个表就行*/
select sname,dept
from student join sc on(student.sno=sc.sno) join course on(course.cno=sc.cno)
where cname='Java';
/*这个中方法看着和上面几乎一样其实不一样,这个是外连接,外链接有left 和 right 而内连接在join前面是inner,inner可以不写*/
select s.sname,s.dept from Course c left join SC sc on c.cno=sc.cno left join Student s on sc.sno=s.sno
where c.cname='Java'
(4)统计每个系的学生的考试平均成绩。
select dept,avg(grade) 平均成绩
from student join sc on(student.sno=sc.sno)
group by dept;
select s.dept,avg(sc.grade) from Student s left join SC sc on s.sno=sc.sno group by s.dept
(5)统计计算机系学生每门课程的选课人数、平均成绩、最高成绩和最低成绩。
/*初学者看到这个查询可能有点不知如何下手,其实一步一步分析很简单的,
第一步看要查询的什么,
第二步根据查询的内容确定表和表之间的关系,
第三步把需要联系的表连起来
第四步看前面的定语,比如这个要查计算机系的
第五考虑用什么机构的语句查询*/
/*avg()求平均值,可以在()给出具体要求的平均值的数据源
max()用法和avg一样,这个是求最大值的
min()求最小值*/
select course.cno,count(student.sno) as 选课人数,avg(grade) as 平均成绩,max(grade) as 最高分,min(grade) as 最低分
from student join sc on(student.sno=sc.sno) join course on(course.cno=sc.cno)
where dept='计算机系'
group by course.cno;
select sc.cno,count(s.sno),avg(sc.grade),max(sc.grade),min(sc.grade) from Student s left join SC sc on s.sno=sc.sno
where s.dept='计算机系' group by sc.cno
(6)查询与刘晨在同一个系学习的学生的姓名和所在的系。
/*这是同表查询,这个语句和下面的一个查询出的结果不一样可以试下,一个包含了刘晨一个没有包含
这里就用到表的别名这也是一种用法*/
select s2.sname,s2.dept
from student s1 join student s2 on (s1.dept=s2.dept)
where s1.sname='刘晨' and s2.sname!='刘晨';
select Sname,Dept from Student
where Dept=(select Dept from Student where Sname='刘晨')
(7)查询与“数据结构”在同一个学期开设的课程的课程名和开课学期。
select c2.cname,c2.semester
from course c1 join course c2 on c1.semester=c2.semester
where c1.cname='高等数学' and c2.cname!='高等数学';
select Cname,Semester from Course
where Semester=(select semester from Course where Cname='高等数学')
(8)查询至少被两个学生选的课程的课程号。
select Cno,count(Sno) from SC group by Cno having count(Sno)>=2
(9)查询全体学生的选课情况,包括选修了课程的学生和没有选修课程的学生。
select * from Student left join SC on(Student.Sno=SC.Sno);
select s.sno,sname,cno,grade from student s left join sc on s.sno = sc.sno
select * from Student inner join SC on Student.Sno=SC.Sno
(10)查询没人选的课程的课程名。
select c.cno,cname from course c left join sc on c.cno = sc.cno where sc.cno is null
select Cname from Course where Cno not in (select distinct(Cno) from SC)
(11)查询计算机系没有选课的学生,列出学生姓名和性别。
select sname,ssex from student s left join sc on s.sno = sc.sno
Where s.dept = '计算机系' and sc.sno is null;
(12)统计计算机系每个学生的选课门数,包括没有选课的学生。
select s.Sname,count(sc.cno) 选课门数 from Student s left join SC sc on s.sno=sc.sno
where s.dept='计算机系' group by s.Sname;
(13)查询信息管理系选课门数少于3门的学生的学号和选课门数,包括没有选课的学生。
查询结果按选课门数递增排序。
select s.sno,count(sc.cno) 选课门数 from Student s left join SC sc on s.sno=sc.sno
where s.dept='信息管理系' group by s.sno having count(sc.cno)<3 order by count(sc.cno);
(14)查询考试成绩最高的三个成绩,列出学号、课程号和成绩。
select * from SC
where grade is not null and rownum<=3 order by grade desc
(15) 查询Java考试成绩最高的前三名的学生的姓名、所在系
select s.sname,s.dept from Student s left join SC sc on s.sno=sc.sno left join Course c on sc.cno=c.cno
where rownum<=3 and c.cname='Java' order by sc.grade desc;
(16)查询选课人数最少的两门课程(不包括没有人选的课程),列出课程号和选课人数。
select * from (select c.cno,count(sc.sno) from Course c left join SC sc on c.cno=sc.cno
group by c.cno having count(sc.sno)>0 order by count(sc.sno)) where rownum<=2;
(17)查询计算机系选课门数超过2门的学生中,考试平均成绩最高的前2名(包括并列的情况)学生的学号、选课门数和平均成绩。
/*查询嵌套,查询里有一个子查询*/
select * from (select sc.sno,count(sc.cno),avg(sc.grade) from Student s left join SC sc on s.sno=sc.sno
where s.dept='计算机系' and sc.sno is not null group by sc.sno having count(sc.sno)>2 order by avg(sc.grade) desc)
where rownum<=2
(18)将计算机系的学生信息保存到#ComputerStudent局部临时表中。
create global temporary table ComputerStudent on commit preserve rows as select * from student where dept='计算机系';
select * from ComputerStudent;
(19)将选了Java课程的学生的学号及成绩存入永久表Java_Grade中。
create table Java_Grade as select sc.sno,sc.grade from sc left join course on sc.cno=course.cno
where course.cname='Java';
select* from Java_Grade;
(20)统计每个学期开设的课程总门数,将结果保存到永久表Cno_Count表中
create table Cno_Count as
select course.semester as 学期,count(course.cno) as 总门数 from course group by semester;
select Semester,count(Cno) 总门数 from Course group by Semester
select * from Cno_Count;
(21)查询第2学期总学分和课程总门数。
select sum(credit),count(cno) from course
where semester=2;
select sum(credit) 总学分,count(Cno)总门数 from Course where Semester=2
2、在st账户中,完成以下多表的高级查询操作。
(1)查询选了Java课程的学生的学号、姓名、所在系和成绩,并对所在系进行如下处理:“计算机系”:显示“CS”;“信息管理系”:显示“IM”;“通信工程系”:显示“COM”。
select s.sno,s.sname,sc.grade,case s.dept
when '计算机系' then 'CS'
when '信息管理系' then 'IM'
when '通信工程系' then 'COM'
end as 所在系
from student s left join Sc sc on s.sno = sc.sno left join course c on sc.cno=c.cno
where c.cname='Java'
select s.sno,s.sname,case s.dept
when '计算机系' then 'CS'
when '信息管理系' then 'IM'
when '通信工程系' then 'COM'
end as 所在系,sc.grade 成绩
from student s left join Sc sc on s.sno = sc.sno left join course c on sc.cno=c.cno
where c.cname='Java'
(2)查询“C001”课程的考试情况,列出学号和成绩,对成绩进行如下处理:如果成绩大于等于90,
则在查询结果中显示“优”;如果成绩在80到89分之间,则在查询结果中显示“良”;如果成绩在70到79分之间,
则在查询结果中显示“中”;如果成绩在60到69分之间,则在查询结果中显示“及格”;如果成绩小于60分,则在查询结果中显示“不及格”。
select Sno,case
when Grade>=90 then '优'
when Grade >=80 and Grade <=89 then '良'
when Grade >=70 and Grade <=79 then '中'
when Grade >=60 and Grade <=69 then '及格'
when Grade <60 then '不及格'
end as 考试情况
from SC where Cno='c001'
select sno 学号,grade 成绩,case
when grade >= 90 then '优'
when grade >= 80 and grade < 90 then '良'
when grade >= 70 and grade <=79 then '中'
when grade >= 60 and grade <= 69 then '及格'
when grade < 60 then '不及格'
end as 考试情况
from sc where cno='c001'
select * from sc;
(3)统计每个学生的考试平均成绩,列出学号、考试平均成绩和考试情况,其中考试情况的处理为:
如果平均成绩大于等于90,则考试情况为“好”;如果平均成绩在80~89,则考试情况为“比较好”;
如果平均成绩在70~79,则考试情况为“一般”;如果平均成绩在60~69,则考试情况为“不太好”;
如果平均成绩低于60,则考试情况为“比较差”。
select Sno,avg(Grade),case
when avg(Grade)>=90 then '好'
when avg(Grade)>=80 and avg(Grade)<=89 then '比较好'
when avg(Grade)>=70 and avg(Grade)<=79 then '一般'
when avg(Grade)>=60 and avg(Grade)<=69 then '不太好'
when avg(Grade)<60 then '比较差'
end as 考试情况
from SC group by Sno
select sno 学号,avg(grade) 平均成绩,case
when avg(grade) >= 90 then '好'
when avg(grade) >=80 and avg(grade) <=89 then '比较好'
when avg(grade) >= 70 and avg(grade) <= 79 then '一般'
when avg(grade) >=60 and avg(grade) <=69 then '不太好'
when avg(grade) <60 then '比较差'
end as 考试情况
from sc group by sno order by avg(grade)desc
(4)统计计算机系每个学生的选课门数,包括没有选课的学生。
列出学号、选课门数和选课情况,其中对选课情况的处理为:
如果选课门数超过4,则选课情况为“多”;如果选课门数在2~4,则选课情况为“一般”;
如果选课门数少于2,则选课情况为“少”;如果学生没有选课,则选课情况为“未选”。并将查询结果按选课门数降序排序。
/*这里用到了case 字句,他的作用就是转换显示的
结构:case
when ... then..
when... then..
end
具体用法看下面案例
*/
select s.sno,count(cno),case
when count(cno) > 4 then '多'
when count(cno) >=2 and count(cno) <= 4 then '一般'
when count(cno) < 2 and count(cno)>0 then '少'
when count(cno) = 0 then '未选'
end as 选课情况
from student s left join sc on s.sno = sc.sno where s.dept='计算机系' group by s.sno order by count(cno) desc
select s.sno,count(sc.cno),case
when count(sc.cno)>4 then '多'
when count(sc.cno) between 2 and 4 then '一般'
when count(sc.cno) between 1 and 2 then '少'
when count(sc.cno)=0 then '未选'
end as 选课情况
from Student s left join SC sc on s.sno=sc.sno where s.dept='计算机系' group by s.sno
(5)查询与“刘晨”在同一个系学习的学生。
select s2.sno,s2.sname,s2.ssex,s2.sage,s2.dept from student s1 left join student s2 on s1.dept=s2.dept
where s1.sname='刘晨'and s2.sname!='刘晨'
(6)查询考试成绩大于90分的学生的学号和姓名。
select Sno,Sname from Student where Sno in (select Sno from SC where Grade>90)
select s.sno,s.sname from Student s left join SC sc on s.sno=sc.sno where sc.grade>90
select student.sno,student.sname,grade
from student left join sc on student.sno=sc.sno
where grade>90;
(7)查询计算机系选了“C002”课程的学生,列出姓名和性别。
select s.sname 姓名,s.ssex 性别
from student s left join sc on s.sno=sc.sno
where cno='c002'and dept='计算机系'
/*这是个子查询,当两个表没有键关系时,我们要的数据又在两个表里,我们就可以用这种方法,注意这样方法也不是一点要求没有的他们要函数相同列名*/
select Sname,Ssex from Student
where Sno in (select Sno from SC where Cno='c002') and Dept='计算机系'
(8)查询选修了“Java”课程的学生的学号和姓名。
select sno,sname from student
where sno in (select sno from sc where cno in(select cno from course where cname='Java'))
(9)统计选了Java课程的这些学生的选课门数和平均成绩。
select sno,count(cno) 选课门数,avg(grade)
from sc
where sno in (select sno from sc where cno in(select cno from course where cname='Java'))
group by sno
select Sno,count(Cno),avg(Grade) from SC
where Sno in(select Sno from SC inner join Course on SC.Cno=Course.Cno where Course.Cname='Java') group by Sno
(10)查询选了“JAVA”课程的学生学号、姓名和JAVA成绩。
select student.sno 学号,student.sname 姓名,sc.grade Java成绩
from student left join sc on student.sno=sc.sno left join course on course.cno=sc.cno
where cname='Java'
select Student.Sno,Student.Sname,SC.Grade from Student inner join SC on Student.Sno=SC.Sno inner join Course on SC.Cno=Course.Cno
where Course.Cname='Java'
(11)查询选了“C004”号课程且成绩高于此课程的平均成绩的学生的学号和成绩。
select sno,grade from sc
where grade>(select avg(grade) from sc where cno='c004') and cno='c004'
select Sno,Grade from SC where Cno='c004' and Grade >(select avg(Grade) from SC where Cno='c004')
(12)查询考试平均成绩高于全体学生的总平均成绩的学生的学号和平均成绩。
select sno,avg(grade) from sc
group by sno having avg(grade)>(select avg(grade)from sc)
(13)查询没选“C001”号课程的学生姓名和所在系。
select Sname,Dept from Student where Sno not in (select Sno from SC where Cno='c001')
(14)查询计算机系没选JAVA课程的学生姓名和性别。
select sname,ssex from student
where sno not in (select sno from sc inner join course on sc.cno=course.cno where cname = 'Java')and dept='计算机系'
select Sname,Ssex from Student
where Sno not in (select Sno from SC inner join Course on SC.Cno=Course.Cno where Course.Cname='Java') and Dept='计算机系'
(15) 查询其他学期开设的课程中比第1学期开设课程的学分少的课程名、开课学期和学分。
/*注意some的使用*/
select cname,semester,credit from course
where credit< some (select credit from course where semester=1)and semester!=1
select * from Course where Credit< some(select Credit from Course where Semester =1) and Semester!=1
(16)查询至少有一次成绩大于等于90的学生的姓名,所修的课程号和成绩。
select s.sname,sc.cno,sc.grade from Student s left join SC sc on s.sno=sc.sno
where s.sno in(select Sno from SC where Grade>=90)
select s.sname,sc.cno,sc.grade from Student s left join SC sc on s.sno=sc.sno
where s.sno=some(select Sno from SC where Grade>=90)
(17)查询比第1学期开设的所有课程的学分都小的其他学期开设的课程名、开课学期和学分。
select cname,semester,credit from course
where credit< all(select credit from course where semester=1)and semester!=1
select Cname,Semester,Credit from Course where Credit <all(select Credit from Course where semester=1) and Semester!=1
(18)查询每个学期学分最低的课程的课程名、开课学期和学分。
select Cname,Semester,Credit from Course c1
where Credit in (select min(Credit) from Course c2 where c1.semester=c2.semester)
(19)查询每门课程考试成绩最高的两个学生的学号以及相应的课程号和成绩。不包括没考试的课程。
select sc.*,rank()over(partition by cno order by grade desc) rd from sc;
select * from (select sc.*,row_number()over(partition by cno order by grade desc) rd from sc)
where rd<=2;
(20)查询每门课程中,考试成绩低于该门课程的平均成绩的学生的学号和成绩。
select sno,grade from sc sc1
where grade<(select avg(grade)from sc sc2 where sc1.cno=sc2.cno)
select Cno,Sno,Grade from SC sc1 where Grade <(select avg(Grade) from SC sc2 where sc1.cno=sc2.cno)
/*因为查询的是考试成绩低于该门课程的平均成绩的学生的学号和成绩,所以下面这样写使不对的,下面的是每门课低于总平均成绩的*/
select Cno,Sno,Grade from SC where Grade <(select avg(Grade) from SC )
(21)查询有最高学分超过本学期平均学分1.5倍的学期。
select Semester from Course c1 group by Semester having max(Credit)>=all(select 1.5*avg(Credit)
from Course c2 where c1.semester=c2.semester)
select semester from course c1 group by semester having max(credit)>=all(select 1.1*avg(credit)from course c2 where c1.semester=c2.semester)
(22)查询学生姓名、所在系和该学生选的课程门数。
select sname,dept,(select count(cno)from sc where sc.sno=student.sno) 选课门数 from student
(23)查询课程名、开课学期及选该门课的学生人数、平均成绩。不包括没人选的课程。
select Cname,Semester 学分,
(select count(*) from SC where SC.Cno=Course.Cno) as 选课人数,
(select avg(Grade) from SC where SC.Cno=Course.Cno) as 平均成绩 from Course
3.总结: