什么是子查询?
使用子查询解决问题:谁的工资比SCOTT高?
子查询的语法
- 子 查 询 ( 内 查 询 ) 在 主 查 询 之 间 一 次 执 行 完 成 。 \color{red}{子查询(内查询)在主查询之间一次执行完成。} 子查询(内查询)在主查询之间一次执行完成。
- 子 查 询 的 结 果 被 主 查 询 使 用 ( 外 查 询 ) 。 \color{red}{子查询的结果被主查询使用(外查询)。} 子查询的结果被主查询使用(外查询)。
子查询的类型
单行子查询
- 只返回一条记录
- 单行操作符
操作符 | 含义 |
---|---|
= | Equalto |
> | Greaterthan |
>= | Greaterthanorequalto |
< | Lessthan |
<= | Lessthanorequalto |
<> | Notequalto |
示例1:
select ename,job,sal
from emp
where job=
(select job
from emp
where empno=7566) and sal >
(select sal
from emp
where empno=7782);
示例2:
select ename,job,sal
from emp
where sal=
(select min(sal)
from emp);
示例3:
select deptno,min(sal)
from emp
group by deptno
having min(sal) >
(select min(sal)
from emp
where deptno=20);
示例4:
查询出比雇员7654的工资高,同时从事和7788的工作一样的员工
select *
from emp t1
where t1.sal>
(select t.sal
from emp t
where t.empno=7654) and t1.job=
(select t2.job
from emp t2
where t2.empno=7654);
示例5:
要求查询每个部门的最低工资和最低工资的雇员和部门名称
select d.dname, a.minsal, e.ename
from dept d,
(select deptno, min(sal) minsal
from emp
group by deptno) a,emp e
where d.deptno=a.deptno and e.sal=a.minsal;
非法使用单行子查询示例
select empno,ename
from emp
where sal=
(select min(sal)
from emp
group by deptno);
多行子查询
- 返回了多条记录
- 多行操作符
操作符 | 含义 |
---|---|
IN | 等于列表中的任何一个 |
ANY | 和子查询返回的任意一个值比较 |
ALL | 和子查询返回的所有值比较 |
示例:in 在集合中
查询部门名称是SALES和ACOUNTING的员工
select * from emp where deptno in
(select deptno from dept where dname='SALES' or dname='ACCOUNTING');
示例:any 和集合中的任意一个值比较
查询工资比30号部门员工高的员工信息
select * from emp where sal > any
(select sal from emp where deptno=30);
示例:all 和集合中的所有值比较
查询工资比30号部门所有员工高的员工信息
select * from emp where sal > all
(select sal from emp where deptno=30);
子查询需要注意的问题
- 括号
- 合理的书写风格
- 可以在主查询的where、select、having、from后面使用子查询
- 不可以在group by使用子查询
- 强调from后面的子查询
- 主查询和子查询可以不是同一张表;只有子查询返回的结果 主查询可以使用 即可
- 一般不在子查询中排序;但在top-n分析问题中,必须对子查询排序
- 一般先执行子查询,再执行主查询;相关子查询列外
- 单行子查询只能使用单行操作符;多行子查询只能使用多行操作符
- 子查询中的null
示例:在select语句后使用子查询
注意:select语句后的子查询必须是单行子查询
查询员工号,姓名,薪水,7839的职位
select empno,ename,sal,
(select job
from emp
where empno=7839)
from emp;
示例:在from语句后面使用子查询
查询员工信息:员工号,姓名,月薪
select *
from (select empno, ename, sal from emp);
示例:top-n分析问题
rownum行号:
- rownum永远按照默认的顺序生成
- rownum只能使用小于等于,不能使用大于等于
查询员工表中工资最高的前三名
select rownum, empno, ename, sal
from (select * from emp order by sal desc)
where rownum <= 3;
示例:找到员工表中薪水大于本部门平均薪水的员工
select e.empno, e.ename, e.sal, d.avgsal
from emp e, (select deptno, avg(sal) avgsal from emp group by deptno) d
where e. deptno=d.deptno and e.sal > d.avgsal;
相关子查询:
将主查询中的值 作为参数传递给子查询
使用相关子查询解决上面的示例
select empno, ename, sal, (select avg(sal) from emp where deptno=e.deptno) avgsal
from emp e
where sal > (select avg(sal) from emp where deptno=e.deptno);
示例:统计每年入职员工的个数
select count(*) Total,
sum(decode(to_char(hiredate, 'yyyy'), '1980', 1, 0)) "1980",
sum(decode(to_char(hiredate, 'yyyy'), '1981', 1, 0)) "1981",
sum(decode(to_char(hiredate, 'yyyy'), '1982', 1, 0)) "1982",
sum(decode(to_char(hiredate, 'yyyy'), '1987', 1, 0)) "1987"
from emp;
子查询中的null值问题
-
单行子查询中的null值问题
- 多行子查询中的null值问题
示例:查询不是老板的员工查询错误,集合中有null值不可以使用not in
Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。
它的内容包括:
- 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
- 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
- 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
- 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
- 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
- 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
- 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
- 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw
目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:
想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询
同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。