mysql笔记(8)-嵌套查询之in、exists

本文将简单介绍in从句和exists从句在嵌套查询中的用法

当我们需要使用嵌套查询来完成更复杂的检索时
可以在where从句内添加in或exists从句

一、in

1、单个属性待筛选

在这种情况下,in从句的格式为

select xxx
from table_name
where column_name in
(select xxx
from xxx);  

下面用一个具体的例子来说明:
8-1.png
在section(排课)表中,我们想找出 在2009年秋季和2010年春季都有开课的课程id

select distinct course_id
from section  
where semeter='Fall' and year=2009 and 
course_id in 
(select course_id
from section
where semeter='Spring' and year=2010);

同理可得
如果我们想找出 在2009年秋季开课 但不在2010年春季开课的课程id
只需要在in之前添加 not 即可

执行顺序的说明:
在上述查询中
数据库系统将会先执行in从句内的查询
也就是说 先返回一张临时表(表内是2010年春季有开课的课程信息)
再在临时表中 执行外层的查询
即 在临时表中 筛选出在2009年秋季有开课的课程

2、多个属性待筛选

在这种情况下,待筛选的多个属性需要写成属性组的形式,放在一对圆括号内

select xxx
from table_name
where (column1_name, column2_name) in
(select xxx
from xxx);  

下面用一个具体的例子来说明:
8-2.png

补充说明:属性组(course_id, sec_id, semester, year)能够唯一地标识一门已经开过课的课程)

在takes(学生选课)表和teaches(教师教课)表中
我们想找出 参加了由ID为10101的教师所教的课的学生ID

select distinct takes.ID  
from takes
where (course_id, sec_id, semester, year) in
(select course_id, sec_id, semester, year
from teaches
where ID=10101);

二、exists

exists从句的写法为

select xxx
from table_name
where exists (subquery);

与in从句截然不同的是
写在圆括号内的内查询并不返回一张表
而是返回一个布尔值 (true 或者 false)

下面用具体的例子来说明exists从句的执行过程:
在section(排课)表中,我们想找出 在2009年秋季和2010年春季都有开课的课程id

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);

在这个例子中,内查询的查询条件依赖于外查询中的course_id属性
具体的处理过程如下:
(1) 执行外查询 生成一张临时表(暂记为R)
R中保存了 在2009年秋季有开课的课程信息
(2) 对于R的每一个元组
将其放入内查询中 并验证是否存在符合条件的记录
若存在 则向外层的where返回true
并将这个元组放入结果表中
(3) 重复步骤(2) 直到R中所有元组都被遍历
也就是说 若外查询所生成的临时表有N个元组
那么内查询将会执行N次

原文地址:https://www.cnblogs.com/baebae996/p/12909246.html