一、什么是子查询?
一个查询语句嵌套在另一个查询语句内部的查询。在实际应用中,有时候一个查询语句的条件需要另一个查询语句来获取。
二、查询规范
1.子查询必须放在小括号中
2.子查询一般放在比较操作符的右边,以提高代码的可读性。
3.子查询可以出现在几乎所有的SELECT子句中。(如:SELECT、FROM、WHERE、ORDER BY、HAVING子句)
三、子查询分类
根据子查询返回的数据分类
- 标量子查询:返回1行1列一个值
- 行子查询:返回的结果集是 1 行 N 列
- 列子查询:返回的结果集是 N 行 1列
- 表子查询:返回的结果集是 N 行 N 列
根据子查询和主查询之间是否有条件关联分类
- 相关子查询:两个查询之间有一定的条件关联(相互联系)
- 不相关子查询:两个查询之间没有条件关联(相互独立)
四、四种子查询
技巧:先将子查询单独写出来,再放进主查询中。
1.标量子查询
举例:查询出工资比LILY低的全部员工信息
SELECT *
FROM emp
WHERE sal<(SELECT sal FROM emp WHERE eanme='LILY');
括号里的就是子查询,返回了一个单行单列的数据,用于与sal进行比较。
2.单行子查询
举例:查询与LILY从事同一工作且工资相同的员工信息
SELECT *
FROM emp
WHERE (job,sal)=(SELECT job,sal FROM emp WHERE ename='SCOTT');
这里子查询返回了两个字段job和sal,一条数据,同样也是用于where子句进行比较。
3.多行子查询
结合操作符来讲
- IN 等于列表中(一个字段中的多个数据)的任意一个
SELECT *
FROM emp
WHERE sal IN(SELECT MIN(sal) FROM emp GROUP BY deptno);
例子中,MIN函数会在每个分组中取最低值,多个分组就形成了多行且一个字段(单列)。IN则表示只要sal符合其中一个就成立。
- ANY 需要和单行比较操作符一起使用(>、<、=、<>…),与子查询结果中任何一个值比较,一个成立
SELECT *
FROM emp
WHERE sal >ANY(
SELECT MIN(sal) FROM emp WHERE job='MANAGER' GROUP BY deptno);
这里ANY则取任意一个子查询中的到的列表。sal大于这个ANY(…)则表示只要大于其中一个值就成立,也等价于大于列表中最小的值。
- ALL 需要和单行比较操作符一起使用(>、<、=、<>…),和子查询返回的所有值比较,同时成立。
ALL则表示取列表中的所有值。如果sal>ALL(…)则表示sal要大于列表中的所有值,等价于大于最大值。 - SOME 实际上是ANY的别名,作用相同,一般用ANY
4.表子查询
子查询返回的是多行多列的数据,就是一个表格。
举例:查询与10号部门任何一个员工入职日期和领导相同的员工信息。
这里任何一个就提示了多列,入职日期和领导两个字段多行,形成了一个表格的结构。
select *
from emp
where (YEAR(hiredate),mgr)IN(select YEAR(hiredate),mgr from emp where deptno=10);
表子查询形式多样,有简单的也有较难的,建议多找些题进行练习。包括在from子句中,select子句,HAVING子句中的使用等等。