版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
目录
exists和not exists语句
where中带有exists语句的执行次序比较特殊,它的执行次序是从主语句中每次取一行,将这一行的输入到子语句中执行,如果这行数据输入到子语句中,子语句的select不是空值的话,返回true,也就是就这行数据应该被选择。(因为where是根据逻辑true和false来判断是否选择这行数据)
/*列出选修了01号课程的学生的学号及姓名*/
select SNO,SNAME
from student
where exists(select *
from sc
where CNO='153701'
and student.SNO=student.SNO)
/*列出同时选修001号和002号课程的学生的学号*/
select SNO
from sc as sc1
where sc1.CNO='153701' and
exists(select SNO
from sc as sc2
where sc2.CNO='216301'
and sc2.SNO=sc1.SNO)
-- or
select sc1.SNO
from sc as sc1,sc as sc2
where sc1.SNO=sc2.SNO
and sc1.CNO='153701'
and sc2.CNO='216301'
有时候,我们使用双重否定表示肯定,比如说对于下面这个任务来讲:对于任意课程,所求学生选之 = 不存在任何一门课程,所求学生没有选之。
/*列出选修了全部课程的学生姓名*/
select SNAME
from student
where not exists(select CNO --选择出这个学生所有没选的课程
from course
where not exists( --对于这个学生的这个课,判断有没有选,选择出没选的课
select *
from sc
where sc.CNO=course.CNO
and sc.SNO=student.SNO))
对于下面这个任务,可以找到这样的双重否定关系:任意课程,001号学生选之,所求学生选之 = 不存在任何一门课程,001号学生选之,所求学生没有选之。
/*列出至少选修了001号学生选修的所有课程的学生名*/
select SNAME
from student
where not exists(select CNO --选择出对于指定学生来讲,不存在任何一门课程,001号学生选择,他没有选择
from course
where exists(select * --选择出对于指定学生来讲,对于001号学生选的课中,他没有选择
from sc
where sc.CNO=course.CNO
and sc.SNO='001'
and not exists(select * --选择出对于指定学生的指定课程(这个课程是001号同学选过的),没有选择的学生
from sc
where sc.CNO=course.CNO
and sc.SNO=student.SNO)))
derived relations 派生关系
derived relations 派生关系,我们允许在from从句中使用子查询表达式
/*找到所有平均成绩大于90的学生*/
select SNO,AVG_GRADE
from (select SNO,AVG(GRADE)
from sc
group by SNO)
as sno_avg(SNO,AVG_GRADE)
where AVG_GRADE>90
with语法
with提供一个临时定义视图的方式,该临时视图只在with出现的语句中可用,并没有真正存入视图中。
/*找到有最大GRADE的学生*/
with max_grade(SNO,value) as --将子查询结果作为临时视图max_grade进行保存
(select SNO,MAX(GRADE)
from sc
group by SNO)
select SNO,GRADE
from sc
where GRADE=(select MAX(max_grade.value)
from max_grade)
go
view 视图
1.视图是命名的、从基本表中导出的虚表,它在物理上并不存在,存在的只是它的定义
2.视图中的数据是从基本表中导出的,每次对视图查询都要重新计算
/*建立选修线性代数课的学生的视图*/
go
create view xsds_stu(SNO)
as (select SNO
from sc,course
where sc.CNO=course.CNO
and CNAME='线性代数')
go
/*创建一个临时视图,保存所有课程成绩大于90的学生信息*/
with grade_up_90(SNO,GRADE) as
(select SNO,GRADE
from sc
where GRADE>90)
select *
from grade_up_90
go
delete语句
delete 删除表中元组,一次只能从一张表中删除元组。
/*删除成绩低于60分的学生*/
delete from student
where SNO in
(select SNO
from sc
where sc.GRADE<60)
delete from sc
where GRADE<60
insert语句
insert 插入语句,向指定表中一次性插入一个或者多个元组。
insert into student(SNO,SNAME,AGE,SEX,DNO,BIRTHDAY)
values('2810126','李好洋',21,'男','0001','1999-05-01')
drop table语句
/*创建一个新表excellent来保存成绩大于90的学生信息*/
create table excellent(SNO char(8) not null ,
GRADE float)
go
/*使用drop table删除整个表*/
drop table excellent
go
alter table
使用alter table改变表的属性,add为添加属性,drop column为删除属性
alter table excellent
add SNO char(8) not null
go
alter table excellent
drop column SNO
go
update语句
用update来对指定列进行更新。
/*例子:将低于70分的同学成绩加10*/
update sc
set GRADE=GRADE+10
where GRADE<70
--将excellent表中的数据进行标号,以下使用循环的方法只能适用于SNO为unique的情况使用
alter table student
add ID float
declare @i int
set @i=1
while @i<(select COUNT(*)
from student)
begin
update student
set ID=@i
where SNO=(select top 1 SNO
from student
where SNO not in(select top (@i-1) SNO
from student))
set @i=@i+1
end
更新视图
更新视图的时候也会更新视图对应的表中的信息。
create view grade_mt_90(SNO,CNO,GRADE)
as(select SNO,CNO,GRADE
from sc
where GRADE>90)
select *
from sc
where SNO='2810126'
insert into grade_mt_90
values('2810126','153701',99)
select *
from sc
where SNO='2810126'
go
对视图的更改最终表现为对表的更改而表中不存在视图的某一属性,或属性的性质不相同,则无法更改,这是一种视图机制。所以一下语句段执行会出错。
create view avg_grade(SNO,AVG_GRADE)
as (select SNO,AVG(GRADE)
from sc
group by SNO)
update avg_grade
set AVG_GRADE=80
where SNO='20052454'
go