MySQL之多表查询2

瘦欲@ 提交于 2020-01-29 05:37:13

子查询

子查询是 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”运算符。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!