3.8.3 空关系测试
3.8.3 空关系测试
exists
相关子查询
子查询只能使用自己定义的相关名称,或者外层查询定义的相关名称
内外层相关名称重名时,内层相关名称有效
not exists
关系A是否包含关系B not exists( B except A)
`SQL`查询 找出选修了Biology系开设的所有课程的学生
找出Biology系开设的所有课程集合
找出`S.ID`选修的所有课程
exists
相关子查询
子查询只能使用自己定义的相关名称,或者外层查询定义的相关名称
内外层相关名称重名时,内层相关名称有效
not exists
关系A是否包含关系B not exists( B except A)
`SQL`查询 找出选修了Biology系开设的所有课程的学生
找出Biology系开设的所有课程集合
找出`S.ID`选修的所有课程
3.8.3 空关系测试
SQL
还有一个特性可测试一个子查询的结果中是否存在元组。
exists
exists
结构在作为参数的子查询非空时返回true
值。使用exists
结构,我们还能用另外一种方法书写査询”找出在2009年秋季学期和2010年春季学期同时开课的所有课程“
1 | select course_id |
1 | mysql> select course_id |
上述査询还说明了SQL
的一个特性,来自外层查询的一个相关名称(上述查询中的S)可以用在where
子句的子查询中。
相关子查询
使用了来自外层查询相关名称的子查询被称作相关子查询(correlated subquery
)。
子查询只能使用自己定义的相关名称,或者外层查询定义的相关名称
在包含了子查询的查询中,在相关名称上可以应用作用域规则
。根据此规则,在一个子查询中只能使用此子查询本身定义的,或者在包含这个子查询的任何外部查询中定义的相关名称。
内外层相关名称重名时,内层相关名称有效
如果一个相关名称既在子查询中定义,又在包含该子查询的查询中定义,则子查询中的定义有效。这条规则类似于编程语言中通用的变量作用域规则(重名局部变量覆盖成员变量.)。
not exists
我们可以用not exists
结构测试子查询结果集中是否不存在元组。
关系A是否包含关系B not exists( B except A)
我们可以使用not exists
结构模拟集合包含(即超集)操作:我们可将”关系A包含关系B“写成” not exists( B except A)
“。(尽管contains
运算符并不是当前SQL
标准的一部分,但这一运算符曾出现在某些早期的关系系统中。)
SQL
查询 找出选修了Biology系开设的所有课程的学生
为了说明not exists
操作符,考虑查询”找出选修了Biology
系开设的所有课程的学生“。使用except
结构我们可以书写此查询如下:
1 | select S.ID,S.name |
找出Biology系开设的所有课程集合
1 | select course_id |
1 | mysql> select course_id |
找出S.ID
选修的所有课程
1 | select T.course_ID |
1 | mysql> select S.ID ,T.course_ID |
这样,外层select
对每个学生测试其选修的所有课程集合是否包含Biology
系开设的所有课程集合。