------子查询------
1.返回单行的子查询
返回单行的子查询是内部的select语句结果作为外部语句中条件子句的一部分,其执行结果只有一行记录并向外返回
select stu.sno,stu.sname,stu.sage,stu.sgender,stu.sbirth,stu.sdept from stu where sage = (select sage from stu where sname='林玲');
查询是从最里层的子查询开始,一层一层向外执行,外层的查询可以访问内层查询的结果
子查询可以像一个独立的查询一样进行执行,只不过其查询结果不会显示输出
2.含有聚合函数的单行子查询
select stu.sno,stu.sname,stu.sage,stu..sgender,stu.sbirth,stu.sdept from stu where sage = (select max(sage) from stu);
子查询在父查询中只是起到提供一个条件的作用
3.多表查询中返回结果为单行的子查询
select stu.sno,stu.sname,stu.sage,stu.sgender,stu.birth,stu.sdept from stu where sno = (select sno from grade where score = 70);
在使用单行子查询时,一定要确认子查询只能返回单个值
4.用in谓词实现多行子查询
select stu.sno,stu.sname,stu.sage,stu.sgender,stu.sbirth,stu.sdept from stu where sdept in(select sdept from stu where sname='陈诚');
in谓词可以在前面加上not关键字,表示取反运算,not in表示where子句后的列取值不能是子查询返回结果中的任意一个
5.多表查询中使用in谓词
select sno,sname,sage,sgender,sbirth,sdept from stu where sno in (select sno from grade where score > 70);
一般来说,在具体应用中,如果能用子查询实现的查询,一般不用连接查询;子查询的执行效率也要高于连接查询
6.exists子查询
select sno,sname,sage,sgender,sbirth,sdept from stu where exists(select * from grade where sno = stu.sno and cname='计算机基础');
带有exists的子查询不返回任何实际数据,只产生逻辑真值true或逻辑假值false
exists子查询能取代所有其他子查询,但不是所有的exists子查询都能被其他子查询替代
由exists引出的自查询,其目标列表达式通常都用*表示,因为给出列名也没有实际意义
7.相关子查询
exists子查询的查询条件依赖于外层父查询的某个列值,这类子查询称为相关子查询exists子查询的查询条件依赖于外层父查询的某个列值,这类子查询称为相关子查询
select sno,sname,asge,sgender,sbirth,sdept from stu where 80 <= (select score from grade where sno=stu.sno and grade.cname='计算机基础');
相关子查询的内层查询由于与外层查询有关,因此必须反复求值
8.含聚合函数的相关子查询
select sno,sname,sage,sgender,sbirth,sdept from stu where 2<=(select count(*) from grade where sno=stu.sno);
select sno,sname,sage,sgender,sbirth,sdept from stu where '数据结构' in (select cname from grade where sno=stu.sno);
select sdept,avg(sage) from stu s1 group by s1.sdept having avg(sage) < any(select sage from stu s2 where s1.sdept = s2.sdept);
由于相关子查询中的子查询在父查询返回的结果集上执行,其执行效率一般低于连接查询;但是子查询的性能完全依赖于查询和有关的数据
9.带any的子查询
select sno,sname,sage,sgender,sbirth,sdept from stu where sdept <> '12计算机' and sage < any(select sage from stu where sdept='12计算机');
带any的子查询表示的是于子查询结果中的任意一个值进行比较
10.带all的子查询
select sno,sname,sage,sgender,sbirth,sdept from stu where sdept <> '12计算机' and sage < all(select sage from stu where sdept='12计算机');
带all的子查询表示的是与子查询结果中的所有值进行比较
11.嵌套子查询
嵌套子查询一般用于对三个及三个以上的数据表进行查询
select sno,sname,sage,sgender,sbirth,sdept from stu where sno in (select sno from grade where cname = (select cname from course where cscore = 6)) and sdept = '12计算机' order by sage desc;
在使用嵌套子查询时,应注意一下几个问题:
子查询必须放在圆括号里里面
将子查询放在比较条件的右边以增加可读性
子查询不包含order by子句,对一个select语句只能用一个order by子句,且一般放在最外层的select语句的最后
Oracle支持的嵌套层次最多为255
12.from子句后的子查询
from子句后的子查询以一个记录集的方式提供给父查询作为查询目标表
select * from (select sno,sname,sage,sdept from stu) where sage>22;
在from子句中以子查询代替作为查询对象时,如果其后还包含where子句,那么where子句中的组成条件一定要是子查询能够返回的列值,否则语句执行将出现错误
13.select子句后的子查询
当子查询返回结果只有一行记录时,还可以出现在select子句后作为需返回的列名
select (select sdept from stu where sno = '10001') from stu;
在select子句中以子查询作为返回列名时,子查询中一定要保证返回值只有一个,否则语句执行将出现错误
14.having子句后的子查询
select sdept,count(sdept) from stu group by sdept having sdept in (select sdept from stu where sage>22) order by sdept;
15.子查询返回值为空
一般来讲,子查询的功能是为父查询提供结果记录集,便于父查询进行条件过滤或取值;然而在实际使用过程中,往往会出现子查询返回结果为空值的情况,此时整个select语句将不能找到记录行
select sno,sname,sage,sgender,sdept,sbirth from stu where sdept=(select sdept from stu where ssage<20) order by sno;
由于子查询的特殊性,应该尽量避免让子查询的返回值为null值,因为这会导致父查询的返回结果也为空值