2024-03-19  阅读(49)
原文作者:吴声子夜歌 原文地址: https://blog.csdn.net/cold___play/article/details/100716030
什么是子查询?

使用子查询解决问题:谁的工资比SCOTT高?

202403192030299871.png

子查询的语法

202403192030303442.png

  • 子 查 询 ( 内 查 询 ) 在 主 查 询 之 间 一 次 执 行 完 成 。 \color{red}{子查询(内查询)在主查询之间一次执行完成。} 子查询(内查询)在主查询之间一次执行完成。
  • 子 查 询 的 结 果 被 主 查 询 使 用 ( 外 查 询 ) 。 \color{red}{子查询的结果被主查询使用(外查询)。} 子查询的结果被主查询使用(外查询)。
子查询的类型

202403192030309123.png

单行子查询
  • 只返回一条记录
  • 单行操作符
操作符 含义
= 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);

202403192030313474.png
示例2:

    select ename,job,sal
    from emp
    where sal=
         (select min(sal)
         from emp);

202403192030316525.png
示例3:

    select deptno,min(sal)
    from emp
    group by deptno
    having min(sal) >
          (select min(sal)
          from emp
          where deptno=20);

202403192030319176.png
示例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);

202403192030321687.png
示例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;

202403192030324758.png

非法使用单行子查询示例
    select empno,ename
    from emp
    where sal=
         (select min(sal)
         from emp
         group by deptno);

202403192030328019.png

多行子查询
  • 返回了多条记录
  • 多行操作符
操作符 含义
IN 等于列表中的任何一个
ANY 和子查询返回的任意一个值比较
ALL 和子查询返回的所有值比较

示例:in 在集合中
查询部门名称是SALES和ACOUNTING的员工

    select * from emp where deptno in
           (select deptno from dept where dname='SALES' or dname='ACCOUNTING');

2024031920303321510.png
示例:any 和集合中的任意一个值比较
查询工资比30号部门员工高的员工信息

    select * from emp where sal > any
           (select sal from emp where deptno=30);

2024031920303363811.png
示例:all 和集合中的所有值比较
查询工资比30号部门所有员工高的员工信息

    select * from emp where sal > all
           (select sal from emp where deptno=30);

2024031920303399112.png

子查询需要注意的问题
  • 括号
  • 合理的书写风格
  • 可以在主查询的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;

2024031920303426313.png
示例:在from语句后面使用子查询
查询员工信息:员工号,姓名,月薪

    select * 
    from (select empno, ename, sal from emp);

2024031920303464014.png
示例:top-n分析问题
rownum行号:

  1. rownum永远按照默认的顺序生成
  2. rownum只能使用小于等于,不能使用大于等于

查询员工表中工资最高的前三名

    select rownum, empno, ename, sal
    from (select * from emp order by sal desc)
    where rownum <= 3;

2024031920303490415.png
示例:找到员工表中薪水大于本部门平均薪水的员工

    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;

2024031920303523416.png
相关子查询:
将主查询中的值 作为参数传递给子查询
使用相关子查询解决上面的示例

    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);

2024031920303551817.png

示例:统计每年入职员工的个数

    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;

2024031920303581418.png

子查询中的null值问题
  • 单行子查询中的null值问题

    2024031920303619519.png- 多行子查询中的null值问题
    示例:查询不是老板的员工

    2024031920303657220.png

    2024031920303690521.png查询错误,集合中有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] ,回复【面试题】 即可免费领取。

阅读全文