子查询
子查询是指一个查询语句嵌套在另一个查询语句内部的查询。在 SELECT 子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件。
子查询中常用的操作符有ANY、SOME、ALL、EXISTS、IN,也可以使用比较运算符。子查询可以添加到 SELECT、UPDATE 和 DELETE 语句中,而且可以进行多层嵌套。
在条件表达式中产生标量的子查询
SELECT * FROM score
WHERE id = (SELECT event_id
FROM event
WHERE date='2015-07-01' AND type='Q');
所谓标量,就是单个属性的一个原子值。当子查询出现在 WHERE 子句中的比较运算符(= ,>, >= ,< , <= ,<>)的右边,其输出结果应该只有一个才对。
很容易理解,如果返回多条结果,就无法进行比较,系统就会报错。
又如:
SELECT * FROM teacher WHERE birth = MIN(birth); /*错误*/
这个查询是错的!因为MySQL不允许在子句里面使用统计函数,所以改用子查询:
SELECT * FROM teacher
WHERE birth = (SELECT MIN(birth) FROM teacher);
在条件表达式中产生集合的子查询
如果子查询的输出是一个结果集合,可以通过 ANY、ALL、IN 进行比较。
ANY与SOME
ANY和SOME关键字是同义词,表示满足其中任一条件。它们允许创建一个表达式对子查询的返回结果集进行比较:
SELECT num1
FROM t1
WHERE num1 > ANY(SELECT num2 FROM t2);
上面的子查询返回 t2 的 num2 列,然后将 t1 中的 num1 值与之进行比较,只要大于 num2 的任何一个值,即为符合查询条件的结果。
等价于:
SELECT num1
FROM t1
WHERE num1 > SOME(SELECT num2 FROM t2);
ALL
与ANY/SOME不同,使用ALL时需要同时满足所有内层查询的条件。
SELECT num1
FROM t1
WHERE num1 > ALL(SELECT num2 FROM t2);
上面的子查询还是返回 t2 的 num2 列,然后将 t1 中的 num1 值与之进行比较。但是只有大于所有 num2 值的 num1 才是符合查询条件的结果。
IN
IN关键字后接一个子查询,若在子查询结果集中,返回true,否则返回false。与之相对的是NOT IN。
SELECT num1
FROM t1
WHERE num1 IN (SELECT num2 FROM t2);
在条件表达式中测试空/非空的子查询
EXISTS关键字后接一个任意的子查询,系统对子查询进行运算以判断它是否返回行。
若至少返回一行,那么 EXISTS 的结果为 true,此时外层查询语句将进行查询;
若没有返回任何行,那么 EXISTS 的结果为 false,此时外层语句将不进行查询。
SELECT sName
FROM Student
WHERE EXISTS (SELECT * FROM Grade WHERE gScore < 60);
EXISTS和NOT EXISTS的结果只取决于是否会返回行,而不取决于这些行的内容。
关联子查询
一般的子查询只计算一次,其结果用于外层查询。但关联子查询需要计算多次。
子查询中使用了主查询中的某些字段,主查询每扫描一行都要执行一次子查询,这种子查询称为关联子查询(Correlated Subquery)。
SELECT sName
FROM Student
WHERE '450' NOT IN (SELECT courseID FROM Course
WHERE sID = Student.sID);
上面的子查询中使用了 Student 表的 sID 字段。对于 Student 表中每一个 sID 都会执行一次子查询。
FROM子句中的子查询
子查询可以用括号括起来作为一个关系,从而出现在 FROM 列表中。由于子查询的结果关系没有正式的名字,故必须给它取一个别名。
SELECT *
FROM Grade,
(SELECT * FROM Student WHERE sDept='CS')x
WHERE x.sID=Grade.gID;
x 就是子查询的结果关系的别名。
自学C/C++编程难度很大,如果你想更快提升自己的编程能力和编写项目的水平,欢迎一起共同成长!
UP在主页上传了一些学习C/C++编程的视频教程,有兴趣或者正在学习的小伙伴一定要去看一看哦!会对你有帮助的~
分享(源码、项目实战视频、项目笔记,基础入门教程)
学:
学: