子查询
子查询是 MySQL4.1 提供的新功能,在此之前需要使用表的连接查询来实现子查询的功能。在多数情况下,表的连接查询可以优化子查询效率较低的问题。
所谓子查询是指将一个查询(内层查询)语句嵌套在另外一个查询(外层查询)语句中,内层查询语句的结果为外层查询语句提供查询条件,内层查询要先于外层循环执行。
标量子查询
标量子查询指的是子查询(内层查询)返回的结果是一个单一值的标量,如一个数字或者一个字符串,这种方式是子查询中最简单的返回形式。在标量子查询中可以使用“>”、 “>=”、“<”、“<=”、“=”、“<>”或者“!=”这些比较运算符对子查询的标量结果进行比较,通常子查询的位置在比较式的右侧。
select * from emp
where sal>(select sal from emp where ename='Clark');
行子查询
行子查询指的是子查询(内层查询)返回的结果集是一行 N(N>=1)列,该结果集通 常来自于对表中某条记录的查询。在行子查询中也可以使用“>”、“>=”、“<”、“<=”、 “=”、“<>”或者“!=”这些比较运算符对子查询的结果进行比较,通常子查询的位置在比较式的右侧。
select * from emp
where (job, deptno)=(select job, deptno from emp where ename='Allen');
列子查询
列子查询指的是子查询(内层查询)返回的结果集是 N(N>=1)行一列,该结果通常来自于对表中某个字段的查询。在列子查询中可以使用“IN”、“ANY”、“SOME”、 “ALL”、“EXISTS”操作符,不能直接使用 “>”、“>=”、“<”、“<=”、“=”、 “<>” 或者“!=”这些比较标量结果的比较运算符。
使用IN的列子查询
使用 IN 的列子查询,在开发中经常遇到。 IN 的意思就是判定某个值是否在一个集合中, 如果在就返回 TRUE,否则返回 FALSE,而该集合就是我们列子查询的结果集。我们也可 以使用 NOT IN 来实现外部查询条件不在子查询结果集中的操作。
select * from emp
where deptno in (select deptno from dept where loc in('NewYork','Dallas'));
使用 ANY 或 SOME 的列子查询
ANY 关键词的意思是 “对于子查询返回的结果集中的任何一个数据,如果比较结果为 TRUE,就返回 TRUE,如果比较结果全部为 FALSE,才会返回 FALSE”。
比如“10>ANY(12, 23,5,37)”,由于 10>5,所以该比较式的结果为 TRUE,即只要 10 与集合中的任意一个数 值的比较结果为 TRUE,那么整个比较式就会返回 TRUE。
SOME 是 ANY 的别名,很少使用。
ANY 通常与比较运算符“>”、“>=”、“<”、“<=”、“=”、“<>”或者“!=” 联合使用。
<>ANY:不等于子查询结果中任意一个数据时返回 TRUE,否则返回 FALSE。
select * from emp
where sal < any (select sal from emp where job='clerk');
注意
NOT IN 表示与子查询结果集中所有数据都不匹配时才能返回 TRUE,而<>ANY 表示与子查 询结果集中的任意一个数据不匹配即可返回 TRUE。所以 NOT IN 相当于<>ALL,而与<>ANY 不同。
使用 ALL 的列子查询
ANY 关键词的意思是 “对于子查询返回的结果集中的所有数据,如果比较结果都为 TRUE,才会返回TRUE,如果比较结果中有一个为FALSE,则返回FALSE”。
比如“10>ALL(1, 2,3,4)”,由于 10 大于集合中的所有数据,所以该比较式的结果为 TRUE,即只要 10 大于 集合中的最大值,则返回 TRUE,否则返回 FALSE。
ALL 通常与比较运算符“>”、“>=”、“<”、“<=”、“<>”或者“!=”联合使用。
<>ALL:相当于 NOT IN。
select * from emp
where sal > all (select sal from emp where job='clerk');
使用 EXISTS 的列子查询
EXISTS 关键字表示存在的意思。使用 EXISTS 关键字时,子查询语句返回的并不是查询记录的结果集,而是返回一个布尔值,如果子查询语句查询到满足条件的记录(至少返回 一条记录),则 EXISTS 语句就返回 TRUE,否则返回 FALSE;当子查询返回的结果为 TRUE 时,外层查询语句将进行查询,否则不进行查询。
NOT EXISTS 刚好与之相反。
select * from dept
where exists (select ename from emp where deptno=dept.deptno);
表子查询
表子查询指的是子查询(内层查询)返回的结果集是 N 行 N 列(N>=1),该结果集通 常来自于对表中多条记录的查询。表子查询的结果集可以当做一张临时表来处理,因此这种 子查询通常用在 FROM 子句中。
例如:
select deptno, avg(sal) avg_sal
from emp group by deptno
having avg(sal) like
(select max(avg_sal) from (select deptno, avg(sal) avg_sal from emp group by deptno) sal_level);
使用子查询的注意事项
在使用子查询时,我们需要注意以下事项:
(1) 基于未知值时的查询可以考虑使用子查询;
(2) 子查询必须包含在括号内;
(3) 建议将子查询放在比较运算符的右侧,以增强可读性;
(4) 如果子查询返回单行结果(标量子查询和行子查询),则可以在外层查询中对其使 用相应的单行记录比较运算符,如“>”、“>=”、“<”、“<=”、“=”、“<>”或者“!=”;
(5) 如果子查询返回多行结果(列子查询和表子查询),则此时不允许对其直接使用单 行记录比较运算符,但可以使用“IN”、“ANY”、“SOME”、“ALL”、“EXISTS”运算符。
来源:CSDN
作者:Python'sGod
链接:https://blog.csdn.net/weixin_44733660/article/details/103583969