【SQL Server数据库】对部分SQL语句的理解与使用(二)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_41427568/article/details/102462005

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

猜你喜欢

转载自blog.csdn.net/qq_41427568/article/details/102462005