嵌套语句
在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子句返回真值,表示该条记录可以输出。
结果如图: