第九章:子查询

news2024/10/6 4:08:21

第九章:子查询

9.1:子查询的基本使用

  1. 子查询的基本语法结构

    SELECT ....
    FROM ....
    WHERE expr operator (SELECT ...
                         FROM ...
                         WHERE ...);
    
    • 子查询(内查询)在主查询之前一次执行完成。
    • 子查询的结果被主查询(外查询)使用。
    • 注意事项
      1. 子查询要包含在括号内。
      2. 将子查询放在比较条件的右侧。
      3. 单行操作符对应单行子查询,多行操作符对应多行子查询
  2. 子查询的分类

    • 分类方式1

      我们按内查询的结果返回一条还是多条记录,将子查询分为单行子查询多行子查询

    • 分类方式2

      ​ 我们按内查询是否被执行多次,将子查询划分为相关(或关联)子查询不相关(或非关联)子查询

      ​ 子查询从数据表中查询了数据结果,如果这个数据结果只执行一次,然后这个数据结果作为主查询的条件进行执行,那么这样的子查询叫做不相关子查询。

      ​ 同样,如果子查询需要执行多次,即采用循环的方式,先从外部查询开始,每次都传入子查询进行查询,然后再将结果反馈给外部,这种嵌套的执行方式就称为相关子查询。

9.2:单行子查询

  1. 单行比较操作符

    操作符含义
    =equal to
    >greater than
    >=greater than or equal to
    <less than
    <=less than or equal to
    <>not equal to
  2. 代码示例

    • 返回job_id与141号员工相同,salary比143号员工多的员工姓名,job_id和工资。

      SELECT last_name, job_id,salary
      FROM employees
      WHERE job_id = (
      		SELECT job_id
      		FROM employees
      		WHERE employee_id = 141
      		)
      AND salary > (
      	      SELECT salary 
      	      FROM employees
      	      WHERE employee_id = 143
      	      );
      
    • 返回公司工资最少的员工的last_namejob_idsalary

      SELECT last_name, job_id, salary
      FROM employees
      WHERE salary = (
      		SELECT MIN(salary)
      		FROM employees
      		);
      
  3. HAVING中的子查询

    首先执行子查询,向主查询中的HAVING子句返回结果。

    • 查询最低工资大于110号部门最低工资的部门id和其最低工资

      SELECT department_id, MIN(salary)
      FROM employees
      WHERE department_id IS NOT NULL
      GROUP BY department_id
      HAVING MIN(salary) > (
      		      SELECT MIN(salary)
      		      FROM employees
      		      WHERE department_id = 110
      		      );
      
  4. CASE中的子查询

    • 显示员工的employee_idlast_namelocation。其中,若员工department_idlocation_id为1800的department_id相同,则locationCanada,其余则为USA

      SELECT employee_id, last_name, CASE department_id 
      								WHEN (
          								   SELECT department_id 
                                                FROM departments 
                                                WHERE location_id = 1800) THEN 'Canada'
      								ELSE 'USA' END "location"
      FROM employees;
      
  5. 子查询中的空值问题

    SELECT last_name, job_id
    FROM employees
    WHERE job_id = (
        	# 子查询为NULL
    		SELECT job_id
    		FROM employees
    		WHERE last_name = 'Haas'
    		);
    
  6. 非法使用子查询语句

    # 错误代码:1242
    # Subquery returns more than 1 row
    SELECT employee_id, last_name
    FROM employees
    WHERE salary = (
    		SELECT MIN(salary)
    		FROM employees
    		GROUP BY department_id
    		);
    

9.3:多行子查询

  1. 多行比较操作符

    操作符含义
    IN等于列表中的任意一个
    ANY需要和单行比较操作符一起使用,和子查询返回的某一个值比较
    ALL需要和单行比较操作符一起使用,和子查询返回的所有值比较
    SOME实际上是ANY的别名,作用相同,一般常使用ANY
  2. 实例代码

    • 返回其他job_id中比job_idIT_PROG部门任一工资低的员工的员工号、姓名、job_id以及salary

      SELECT employee_id, last_name, job_id, salary
      FROM employees
      WHERE job_id <> 'IT_PROG'
      AND salary < ANY (
      		  SELECT salary
      		  FROM employees
      		  WHERE job_id = 'IT_PROG'
      		  );
      
    • 返回其他job_id中比job_idIT_PROG部门所有工资都低的员工的员工、姓名、job_id以及salary

      SELECT employee_id, last_name, job_id, salary
      FROM employees
      WHERE job_id <> 'IT_PROG'
      AND salary < ALL (
      		  SELECT salary
      		  FROM employees
      		  WHERE job_id = 'IT_PROG'
      		  );
      
    • 查询平均工资最低的部门id

      # 方式一
      SELECT department_id
      FROM employees
      GROUP BY department_id
      HAVING AVG(salary) = (
      		SELECT MIN(avg_sal)
      		FROM (
      			SELECT AVG(salary) avg_sal
      			FROM employees
      			GROUP BY department_id
      			) t_dept_avg_sal
      		);
      		
      # 方式二
      SELECT department_id
      FROM employees
      GROUP BY department_id
      HAVING AVG(salary) <= ALL(
      		SELECT AVG(salary) avg_sal
      		FROM employees
      		GROUP BY department_id
      		);
      
  3. 空值问题

    • 一行数据都没有

      SELECT last_name
      FROM employees
      WHERE employee_id NOT IN(
      		SELECT manager_id
      		FROM employees
      		);
      

9.4:相关子查询

  1. 相关子查询执行流程

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

    ​ 相关子查询按照一行接一行的顺序执行,主查询的每一行都执行一次子查询。
    在这里插入图片描述

  2. 代码示例

    • 查询员工中工资大于本部门平均工资的员工的last_namesalary和其department_id

      # 方式一: 相关子查询
      SELECT last_name, salary, department_id
      FROM employees e1
      WHERE salary > (
      		SELECT AVG(salary)
      		FROM employees e2
      		WHERE department_id = e1.`department_id`
      		);
      		
      # 方式二: 在FROM中使用子查询
      SELECT e.last_name, e.salary, e.department_id
      FROM employees e, (
      		SELECT department_id, AVG(salary) avg_sal
      		FROM employees
      		GROUP BY department_id) t_dept_avg_sal
      WHERE e.`department_id` = t_dept_avg_sal.department_id
      AND e.salary > t_dept_avg_sal.avg_sal;
      
    • 查询员工的idsalary,按照department_name排序。

      # 在ORDER  BY中使用子查询
      SELECT employee_id, salary
      FROM employees e
      ORDER BY (
      	SELECT department_name
      	FROM departments d
      	WHERE e.`department_id` = d.`department_id`
      	) ASC;
      
  3. EXISTSNOT EXISTS关键字

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

    • 如果在子查询中不存在满足条件的行:条件返回FALSE、继续在子查询中查找
    • 如果在子查询中满足条件的行:不在子查询中继续查找、条件返回TRUE
    • NOT EXISTS关键字表示如果不存在某种条件,则返回TRUE,否则返回FALSE

    查询公司管理者的employee_idlast_namejob_iddepartment_id信息。

    #方式1:自连接
    SELECT DISTINCT mgr.employee_id, mgr.last_name, mgr.job_id, mgr.department_id
    FROM employees emp JOIN employees mgr
    ON emp.manager_id = mgr.`employee_id`;
    
    #方式2:子查询
    SELECT employee_id, last_name, job_id, department_id
    FROM employees
    WHERE employee_id IN (
    		SELECT DISTINCT manager_id
    		FROM employees
    		);
    
    #方式3:使用EXISTS
    SELECT employee_id, last_name, job_id, department_id
    FROM employees e1
    WHERE EXISTS (
    		SELECT * 
    		FROM employees e2
    		WHERE e1.`employee_id` = e2.`manager_id`
    		);
    

    查询departments表中,不存在于employees表中的部门的department_iddepartment_name

    #方式1:
    SELECT d.department_id, d.department_name
    FROM employees e RIGHT JOIN departments d
    ON e.`department_id` = d.`department_id`
    WHERE e.`department_id` IS NULL;
    
    #方式2:
    SELECT department_id, department_name
    FROM departments d
    WHERE NOT EXISTS (
    		SELECT *
    		FROM employees e
    		WHERE d.`department_id` = e.`department_id`
    		);
    
  4. 一个思考题

    • 自连接和子查询两种方式有好坏之分吗?

      ​ 自连接方式好。

      ​ 题目中可以使用子查询,也可以使用自连接。一般情况建议你使用自连接,因为在许多BDMS的处理过程中,对于自连接的处理速度要比子查询快得多。

      ​ 可以这样理解:子查询实际上是通过未知表进行查询后的条件判断,而自连接是通过已知的自身数据表进行条件判断,因此在大部分DBMS中都对自连接处理进行了优化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/618134.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JavaSE】Java(五十五):核心要点总结

文章目录 1. 为什么不允许静态方法访问非静态变量2. Java的内存模型3. 在Java中什么时候用重载什么时候用重写4. 举例说明什么情况下更倾向于用抽象类而不是接口5. 实例化对象有哪几种方式 1. 为什么不允许静态方法访问非静态变量 在Java中&#xff0c;静态方法属于类级别的方法…

【HTML】第 4 节 - 列表标签

欢迎来到博主 Apeiron 的博客&#xff0c;祝您旅程愉快 &#xff01; 时止则止&#xff0c;时行则行。动静不失其时&#xff0c;其道光明。 目录 1、缘起 2、列表 3、无序列表 4、有序列表 5、定义列表 6、总结 1、缘起 微信小程序的列表标签是一种用于展示多个数据项的…

量子 AI,是融合还是颠覆?

光子盒研究院 前言&#xff1a;如今&#xff0c;量子技术早已走出实验室、广泛赋能电力、化学、医学等各个领域&#xff1b;创新赛道上&#xff0c;加速奔跑的量子产业&#xff0c;将带来无限可能。现在&#xff0c;光子盒特开启「量子」专栏&#xff0c;一一解读量子技术将为下…

chatgpt赋能python:Python安装教程:从下载到配置

Python安装教程&#xff1a;从下载到配置 Python作为一门高级编程语言&#xff0c;越来越受到开发人员的欢迎。Python的灵活性和易用性&#xff0c;让许多人选择Python作为他们的程序语言。本文将详细介绍Python安装教程&#xff0c;帮助初学者轻松入门。 1. 下载Python安装包…

【JavaSE】Java(五十四):核心要点总结

文章目录 1. try-catch-finally中 如果 catch 中 return 了&#xff0c;finally 还会执行吗?2. 常见的异常类有哪些3. hashcode 是什么 &#xff0c;有什么作用4. java中操作字符串有哪些类&#xff0c;他们之间有什么区别5. Java 中有哪些引用类型 1. try-catch-finally中 如…

$2$驱动模块

目录 1.驱动模块&#xff08;驱动程序的框架&#xff09; 2.内核中的打印函数&#xff08;编写第一个驱动程序&#xff09; Source Insight 使用&#xff1a; 打印函数编写 分析 3.驱动的多文件编译 4.模块传递参数 安装好驱动之后如何传参&#xff1f; 多驱动之间调用&…

智能照明控制系统在现代建筑工程中的应用 安科瑞 许敏

摘要&#xff1a; 文章分析了在现代建筑工程中智能照明控制系统所具有的优越性&#xff0c;并对如何解决该技术在实际应用中遇到的问题提出了看法与建议。 关键词&#xff1a;智能照明 控制系统 应用节能 引言 随着人们的物质和精神生活水平不断提高&#xff0c;对生活的追求…

MMC整流器Matlab仿真模型子模块个数N=18(含技术文档)

资源地址&#xff1a; MMC整流器Matlab仿真模型子模块个数N&#xff1d;18&#xff08;含技术文档&#xff09;资源-CSDN文库 模型介绍&#xff1a; 1.MMC工作在整流侧&#xff0c;子模块个数N&#xff1d;18&#xff0c;直流侧电压Udc&#xff1d;25.2kV&#xff0c;交流侧…

算法设计与分析期末复习(二)

动态规划 基本思想&#xff1a;把求解的问题分成许多阶段或多个子问题&#xff0c;然后按顺序求解各个子问题。**前一个子问题的解为后一个子问题的求解提供了有用的信息。**在求解任何一子问题时&#xff0c;列出各种可能的局部解&#xff0c;通过决策保留那些有可能达到最优…

Linux面试题汇总

Linux面试题汇总 网络拓展Linux 概述什么是LinuxUnix和Linux有什么区别&#xff1f;什么是 Linux 内核&#xff1f;Linux的基本组件是什么&#xff1f;Linux 的体系结构BASH和DOS之间的基本区别是什么&#xff1f;Linux 开机启动过程&#xff1f;Linux系统缺省的运行级别&#…

javaScript蓝桥杯----外卖给好评

目录 一、介绍二、准备三、⽬标四、代码五、完成 一、介绍 外卖是现代⽣活中必备的⼀环。收到外卖后&#xff0c;各⼤平台软件常常会邀请⽤户在⼝味&#xff0c;配送速度等多个⽅⾯给与评分。在 element-ui 组件中&#xff0c;已经有相应的 Rate 组件&#xff0c;但是已有组件…

前端052_单点登录SSO_单点退出系统

单点退出系统 1、 需求分析2、EasyMock 添加退出系统模拟接口3、定义Api调用退出接口4、定义 Vuex 退出行为1、 需求分析 所有应用系统退出,全部发送请求到当前认证中心进行处理,发送请求后台删除用户登录数据,并将 cookie 中的用户数据清除。 2、EasyMock 添加退出系统模拟…

大数据分析案例-基于LightGBM算法构建银行客户流失预测模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

第四章:运算符

第四章&#xff1a;运算符 4.1&#xff1a;算术运算符 ​ 算术运算符主要用于数学运算&#xff0c;其可以连接运算符前后的两个数值或表达值&#xff0c;对数值或表达式进行加()、减(-)、乘(*)、除(/)、取模(%)运算。 运算符名称作用示例加法运算符计算两个值或表达式的和SE…

chatgpt赋能python:Python如何遍历文件:一篇完整的指南

Python如何遍历文件: 一篇完整的指南 在进行文件操作时&#xff0c;遍历文件是相当普遍的需求。Python中提供了多种方法来遍历文件夹和文件&#xff0c;包括os模块&#xff0c;glob模块和os.walk方法。这篇文章将会介绍这些方法及其应用。 什么是遍历文件&#xff1f; 遍历文…

使用 ConstraintLayout

ConstraintLayout解析 1.前言2.了解ConstraintLayout3.基本用法3.1 看一个布局3.2再看一个布局 1.前言 你是不是一直不敢用ConstraintLayout&#xff0c;是以为属性太多太复杂&#xff1f;你心理上的惰性&#xff0c;畏惧它。它其实很好用很强大&#xff0c;如果要用就需要一个…

Day_40关于图的总结

一. 实际问题的抽象与建模 如果我们需要研究一个实际问题&#xff0c;首先第一步就是对这个实际问题进行抽象&#xff0c;抽象是从众多的事物中抽取出共同的、本质性的特征&#xff0c;而舍弃其非本质的特征的过程。具体地说&#xff0c;抽象就是人们在实践的基础上&#xff0c…

Java中的金钱陷阱

前言 有多少小伙伴是被标题 骗 吸引进来的呢&#xff0c;我可不是标题党&#xff0c;今天的文章呢确实跟”金钱“有关系。 但是我们说的不是过度追求金钱而掉入陷阱&#xff0c;而是要说一说在Java程序中&#xff0c;各种跟金钱运算有关的陷阱。 日常工作中我们经常会涉及到…

chatgpt赋能python:Python字幕滚动:如何让你的视频内容更吸引人

Python字幕滚动&#xff1a;如何让你的视频内容更吸引人 如果你是一位视频创作者&#xff0c;你可能知道如何通过字幕来增加你的视频的吸引力。Python提供了一种简单且高效的方法来制作字幕滚动。字幕滚动是指将文字逐个显示在视频下方&#xff0c;以帮助观众跟上视频的进展。…

让我们彻底了解Maven(一)--- 基础和进阶

Maven大家都很熟悉&#xff0c;但是我们很多人&#xff0c;对它其实都是似乎很熟&#xff0c;但是又好像不熟悉的感觉&#xff0c;包括我&#xff0c;今天咱们就一起来彻底了解Maven的所有功能&#xff0c;我们从入门&#xff0c;到原理剖析&#xff0c;再到实践操作&#xff0…