定义我就不说了,子查询就是内部的查询,包含子查询就是外部查询!也就是说嵌套查询一个是内部查询一个是外部查询,而且查询是由内向外的。
提示一下:在group by和order by中的子查询是没有意义的!
子查询的分类:
- 标量子查询—返回单个值的查询
- 列子查询—返回单属性一列的
- 行子查询—返回多属性一行的
- 表子查询—多行多列
标量子查询可以使用比较运算符(其他的查询不可单独使用比较运算符):
“=, >, <, >=, <=, <>(不等于)”
例子:
select *
from student
where number > (
select count(ID)
from student);
上面的子查询将算出学生的总人数,而外部查询则是找出number大于学生总人数的学生信息。重点是这里的子查询是一个标量子查询,作为一个对比的例子:
select *
from student
where (number, SId) > (
select count(number), count(SId)
from student);
不是标量子查询是不能直接使用比较运算符的,上面是一个错误的例子,即使是两个和两个相比较也是不对的。
以上是标量子查询的特殊之处!!!
接下来讲子查询的共有的操作符:
“any(some), all, in(not in), exists(not exists)”
上面这些操作符,无论是哪种子查询都是可以使用的(包括标量子查询)
- any
任何一个,与一个比较运算符连用
select *
from student
where SId > any(
select SId
from student
where SId > 100);
外部查询中的‘SId’大于任意一个子查询中的‘SId’,那么该查询都会返回true。
和它相对的是all
- all
“所有”,要求大于子查询结果中的所有值
select *
from student
where SId > all(
select SId
from student
where SId > 100);
上面例子,只有外部查询中的SId大于子查询中的所有的SId才是返回true的元祖。
- in(not in)
检查成员资格,可用于枚举集合
select *
from student
where (SId, number) in (
select SId, number
from student
where number > 100);
只有外部查询中的(SId, number)存在于子查询的结果中时才会返回true。这个外部查询的属性个数必须跟子查询结果的属性个数一致(可以是任意多个)
可用于枚举类型
select *
from student
where number in (100, 200, 300);
select *
from student
where (SId, number) in ((100, 151), (200, 161), (300, 171));
这就是所以说的in可以用在枚举类型中(其他的操作符都不可以)
- exists(not exists)
是一个逻辑运算符,返回true/false
select *
from student
where exists(
select *
from student
where number >100);
只要exists包含的子查询中的结果大于等于一行,那么exists就返回true!
子查询差不多就这样(但是以后要学会优化,毕竟子查询有点慢不是吗?)
我们再来讲一下关于查询的条件问题!
对于一个sql语句,它的筛选条件出现在语句的外部和内部查询中都是有用的并且需要被计算的,考虑下面的sql语句:
select course_id
from section as S
where semester = 'Fall' and year = 2009 and
exists(select *
from section as T
where semester = 'Spring' and year = 2010 and S.course_id = T.course_id);
考虑这个语句,我们外部查询筛选出‘Fall’和2009两个关键字,然后exists仅仅是一个逻辑运算符,返回true/false。那么筛选条件只有外部查询中的两个关键字吗?当然不是,我们观察到内部查询中还有’S.course_id = T.course_id’,这个语句也会对外部查询的一个筛选条件。
也就是说这个sql语句最终的关键字有"Fall", 2009, “Spring”, 2010.这个自己体会一下子就知道了。