子查询其实就是嵌套在其他查询中的查询(以select-from-where语句称为一个查询块,将一个查询快嵌套在另一个查询块的where子句或者having子句中)
#一个子查询中还可以嵌套其它子查询,但是子查询不能使用order by子句
我们对数据的描述是由一张张关系表构成的。比如:学生表中有学生姓名,学生id,学生所在班级号,还有班级表,系表中有班主任等相关信息。
现在,如果我们要查询班主任是张明的所有学生信息:
所以第一步:
select class_num
from class
where class_teacher = '张明';
假设结果为:
1415
1416
第二步:
select student_id
from student
where class_num in (1415,1416);
可以看出关键点就在于class_num需要从一张表获取,另一张表动态的获取到这个查询结果作为查询条件,所以,可合并为
select student_id
from student
where class_num in
(select class_num
from class
where class_teacher='张明');
小结:带where子句的select语句,其实就是能通过一张表的某一列或者几列的信息查询到同一张表中一列或者几列的信息,但是跨越表间信息的时候(表之间有公共属)就可以以这个公共属性为纽带(select语句应该具有和where子句中相同数目的列),来查询别的表的某列的信息,这个过程可以重复,即可以有多个子查询。
(关键是要建立起形象的关系和表内,表之间的可视化的查询动作)
以上这样子查询的查询条件不依赖于父查询,称为不相关子查询
另一种使用:创建计算字段:
select cust_name
cust_state
(select count(*)
from orders
where orders.cust_id = customers.cust_id) as orders
from customers
order by cust_name;
这里想要统计出顾客信息,需要统计出客户的订单数,但是客户表中只有订单id,所以需要利用的另一张表中的信息。
注意:子查询中使用了完全限定列名,因为这是相关子查询
以上这样子查询的查询条件依赖于父查询,称为相关子查询
为了表示更丰富的逻辑,可能使用带有比较运算符或者any.some.all谓词的子查询
比如:查询非计算机系重臂计算机科学系任意一个学生年龄小的学生姓名和年龄
select Sname,Sage
from student
where Sage<any
(select Sage
from student
where Sdept='CS')
and Sdept <> 'CS'
#往往这些谓词表达的逻辑都可以用聚集函数代替,比如=any等价于in谓词,<any等价于<max,<>all等价于not in谓词,<all等价于<min
#带有exists谓词的子查询不反悔任何数据,只产生逻辑真或逻辑假。所以目标表达式通常为*,因为给出列名无意义。
比如:查询选修了一号课程的学生姓名
分析:从sc表的cno联系到student表的sname
select Sname
from Student
where exists
(select *
from sc
where Sno=Student.Sno and Cno='1');
#如果是查询没有选修一号课程的学生,那么将exists改为not exists