SQL Sever 嵌套语句
嵌套语句
在SQL语言中,一个select-from-where语句称为一个查询块。将一个查询块嵌套在另一个查询块where子句或having短语的条件中。就叫做嵌套查询。
首先看看我的表:
(Student表) (SC表)
1、 带有In谓词的子查询
我们先来回顾下普通的in用法:
select * from scwhere cno in('2','1'); --查询课程号为2和1的SC表内元组
结果如图:
其实上面语句等于
select *from sc wherecno='2'or cno='1';
然后我们再用嵌套语句写一下:
select * from sc
where cno in
(select * from sc
where cno='2'or cno='1'
);
我们会发现:
看来in的子句中有多个列存在。。。好吧我们设定为一个,再看看:
select * from sc
where cno in
(select Cno from sc
where cno='2'or cno='1'
);
结果如图:
我们可以总结出,in内的查询块要与where后面一一对应。
上面是为了方便理解,现在我们正式介绍。
目的:查询选择二号课程的学生
select * from student
where studentId in
(select Sno from sc
where cno='2'
);
结果如下:
因为In内条件为单值,所以可以用“=”代替In,该查询语句等价于
select * fromstudent
where studentId =(
select Sno from sc
where cno='2'
);
也可以写成
select student.* fromstudent,sc
where studentId =sc.Snoand sc.Cno='2';
2、带有比较运算的子查询
刚刚我们说了,当in括号内为单列时,in可以换成等号。而等号换成大于小于之类的符号,就成了带有比较运算的子查询了。
我们来看一下应用
目的:找出每个学生超过他自己所有选修课平均成绩的课程号
select student.studentId,student.studentName,x.Cno,x.Grade
from student,sc x
where studentId =x.Sno and x.Grade>=(
select avg(y.grade)
from sc y
where y.Sno=x.Sno
);
结果如图:
上面语句有些复杂,不过耐心看很容易看懂。重点是子查询块的条件,也就是where那里。相当于一个指针指向x表的元组,判断y表内所有与此时x元组学生号相等的元组,取他们的成绩算平均值。通俗讲就是,指针指向x中的一个人,在y表中找到所有这个人的课程信息,计算平均值。比较此时x表指针所指的这条记录里的成绩是不是大于等于刚刚算的平均值,成立就输出。
3、带有any(some)或all谓词的子查询
Any就是任何一个,All就是所有
举个例子就明白了。
目的:寻找挂过科的学生。
select* fromstudent
where student.studentId=any(
select y.Sno
from sc y
where y.Grade<60
);
结果如图:
目的:寻找没挂过科的学生。
select* fromstudent
where student.studentId!=all(
select y.Sno
from sc y
where y.Grade<60
);
结果如图:
4、 带有exists谓词的子查询
Exists代表存在量词“存在”。带有Exists谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”。
目的:查询选了1号课程同学。
select* fromstudent
where exists(
select* from sc
where student.studentId=sc.Sno and Cno='1'
);
使用存在量词Exists后,若内层查询结果非空,则外层的where子句返回真值,表示该条记录可以输出。
结果如图:
SQL没有全称量词,但可以用notexists转换。这个逻辑绕的很麻烦。。。我偷个懒