行业资讯 2025年08月6日
0 收藏 0 点赞 361 浏览 3187 个字
摘要 :

文章目录 ​概念 子查询的分类: 角度一:单行子查询、多行子查询 角度二:相关子查询、不相关子查询(或关联子查询和不关联子查询)(即从内查询是否执行多次的角度) ……




  • ​概念
  • 查询的分类:
    • 角度一:单行子查询、多行子查询
    • 角度二:相关子查询、不相关子查询(或关联子查询和不关联子查询)(即从内查询是否执行多次的角度)
  • 单行子查询:
    • 单行比较操作符:
  • 多行子查询:
  • 多行比较操作符:
  • 多行子查询中的空值问题:
  • 相关子查询:
  • EXISTS与NOT EXISTS
  • 多层自查询的三种经典的查询方式:
    • 方式一:
    • 方式二:
    • 方式三:

    本文主要讲解关于MySQL子查询详解相关内容,让我们来一起学习下吧!

    ​概念

    子查询指一个查询语句嵌套在另一个查询语句内部的查询。很多时候查询需要从结果集中获取数据,或者需要从同一个表中先计算得出一个数据结果,然后与这个数据结果(可能是某个标量,也可能是某个集合)进行比较。

    例:想查询工资比BLACK的工资高的员工的信息

    SELECT ename , sal 
    FROM emp
    WHERE sal > (
                SELECT sal 
                FROM emp 
                WHERE ename = \'BLAKE\'
                );
    

    外部的查询称为外查询(或主查询),内部的查询称为内查询(或子查询)。

    注:

    • 子查询在主查询之前执行完成。
    • 子查询的结果被主查询使用。
    • 子查询要包含在括号内。
    • 将子查询放在比较条件的右侧(建议)。
    • 单行操作符对应单行子查询,多行操作符对应多行子查询。

    子查询的分类:

    角度一:单行子查询、多行子查询

    单行子查询返回一条记录,多行子查询返回多条记录。

    角度二:相关子查询、不相关子查询(或关联子查询和不关联子查询)(即从内查询是否执行多次的角度)

    •  子查询从数据表中查询了数据结果,如果这个数据结果只执行一次,然后这个数据结果作为主查询的条件执行,那么这样的子查询称为不相关子查询。
    • 如果子查询需要执行多次,即采用循环的方式,先从外部查询开始,每次都传入子查询进行查询,然后再将结果反馈给外部,这种嵌套的执行方式就称为相关子查询。

    单行子查询:

    单行比较操作符:

    • 子查询可以放在任何可以用“值”表示的位置。比如WHERE、HAVING里的表达式中,SELECT中的字段中,CASE表达式中等等。
    • 子查询只返回一个结果值,不会返回行。
    • 子查询查询不到结果则返回NULL。
    • 多行子查询的结果不能放在单行比较操作符后使用。

    例,在CASE表达式中使用单行子查询:

    SELECT empno , ename , CASE deptno
    WHEN (
          SELECT deptno
          FROM dept
          WHERE loc = \'NEW YORK\'
         ) 
    THEN \'AAA\'
    ELSE \'BBB\'
    END \'location\' #别名
    FROM emp;
    

    多行子查询:

    多行子查询也称为集合比较子查询,返回多行,使用多行比较操作符。

    多行比较操作符:

    可以将多行子查询的结果当作一张表使用,但是,必须要给此表取别名。

    例如:

    SELECT MIN(sal_avg)
    FROM (
          SELECT AVG(sal) sal_avg
          FROM emp
          GROUP BY deptno
         ) das; -- das即为此表的别名。
    

    多行子查询中的空值问题:

    如果多行子查询的结果的其中一条中出现NULL,用NOT IN加此子查询的结果为空,因为NOT IN实际上会用<>来与每个结果比较,若结果中有空值那么 <>NULL的结果就是NULL,正确的做法应该是将多行子查询的结果中的NULL值过滤掉。

    例:

    SELECT ename
    FROM emp
    WHERE NOT IN (
                  SELECT mgr
                  FROM emp
                  WHERE mgr IS NOT NULL
                 );
    

    相关子查询:

    如果相关子查询的执行依赖于外部查询,通常情况下都是因为子查询中的表用到了外部的表,并进行了条件关联,因此每执行一次外部查询,子查询都要重写计算一次,这样的子查询就是关联子查询。

    相关子查询按照一行接一行的顺序执行,主查询的每一行都执行一次子查询。

    例,查询员工中工资大于本部门平均工资的员工的姓名、薪资、和部门号(使用相关子查询):

    SELECT ename , sal , deptno
    FROM emp e1
    WHERE sal > (
                 SELECT AVG(sal)
                 FROM emp e2
                 WHERE deptno = e1.deptno   #子查询要与主查询做相关联,即主查询中的每一行的执行都要重新执行一次子查询。
                );
    

    在SELECT中除了GROUP BY和LIMIT之外,其他的位置都可以使用子查询。

    EXISTS与NOT EXISTS

    关联子查询通常也会和EXISTS操作符一起来使用,用来检查子查询中是否存在行。

    每一行执行时:

    如果在子查询的结果中不存在行,返回FALSE。

    如果在子查询的结果中存在行,返回TRUE。

    返回FALSE即主查询中的相应的行不会成为主查询的结果,返回TRUE即主查询中的相应的行会成为主查询的结果。

    NOT EXISTS表示如果在子查询的结果中不存在行,则返回TRUE,否则返回FALSE(与EXISTS相反)。

    EXISTS后的子查询并不会返回行,只会返回TRUE或FALSE。

    例:

    SELECT empno , ename , job , deptno
    FROM emp e1
    WHERE EXISTS (
                  SELECT *
                  FROM emp e2
                  WHERE e1.empno = e2.mgr
                  );
    

    当员工是属于管理者时,主查询才会接收到子查询返回的TRUE。

    相关子查询也可以使用到更新、删除操作中,称为相关更新、相关删除。

    多层自查询的三种经典的查询方式:

    例,查询公司中平均工资最高的工作职位:

    方式一:

    步骤:

    ①    先求各部门的平均工资

    ②    再到①中的数据中求出最高的平均工资

    ③    再根据②中的数据对应出最高的平均工资对应的工作职位

    SELECT job
    FROM emp
    GROUP BY job
    HAVING AVG(sal) = (
                       SELECT MAX(avg_sal)
                       FROM (
                             SELECT AVG(sal) avg_sal
                             FROM emp
                             GROUP BY job
                             ) avg_tab
                      );
    

    方式二:

    比起方式一,方式二直接 <= ALL的方式将求最大的平均工资的步骤隐藏在比较操作符中,减少了子查询的次数。

    SELECT job
    FROM emp
    GROUP BY job
    HAVING AVG(sal) >= ALL (
                            SELECT AVG(sal)
                            FROM emp
                            GROUP BY job    
                            );
    

    方式三:

    方式三使用的是先降序排列,再用分页LIMIT的方式,只取第一个记录,取得的即是最高的平均工资,也减少了子查询的次数。

    SELECT job
    FROM emp
    GROUP BY job
    HAVING AVG(sal) = (
                       SELECT AVG(sal) avg_sal
                       FROM emp
                       GROUP BY job
                       ORDER BY avg_sal DESC
                       LIMIT 0,1
                      );
    

    以上就是关于MySQL子查询详解相关的全部内容,希望对你有帮助。欢迎持续关注潘子夜个人博客(www.panziye.com),学习愉快哦!

微信扫一扫

支付宝扫一扫

版权: 转载请注明出处:https://www.zuozi.net/10031.html

管理员

相关推荐
2025-08-06

文章目录 一、Reader 接口概述 1.1 什么是 Reader 接口? 1.2 Reader 与 InputStream 的区别 1.3 …

988
2025-08-06

文章目录 一、事件溯源 (一)核心概念 (二)Kafka与Golang的优势 (三)完整代码实现 二、命令…

465
2025-08-06

文章目录 一、证明GC期间执行native函数的线程仍在运行 二、native线程操作Java对象的影响及处理方…

348
2025-08-06

文章目录 一、事务基础概念 二、MyBatis事务管理机制 (一)JDBC原生事务管理(JdbcTransaction)…

456
2025-08-06

文章目录 一、SnowFlake算法核心原理 二、SnowFlake算法工作流程详解 三、SnowFlake算法的Java代码…

517
2025-08-06

文章目录 一、本地Jar包的加载操作 二、本地Class的加载方法 三、远程Jar包的加载方式 你知道Groo…

832
发表评论
暂无评论

还没有评论呢,快来抢沙发~

助力内容变现

将您的收入提升到一个新的水平

点击联系客服

在线时间:08:00-23:00

客服QQ

122325244

客服电话

400-888-8888

客服邮箱

122325244@qq.com

扫描二维码

关注微信客服号