【MySQL】· 一文了解四大子查询

news2024/11/16 7:26:12

前言

✨欢迎来到小K的MySQL专栏,本节将为大家带来MySQL标量/单行子查询、列子/表子查询的讲解

目录

      • 前言
      • 一、子查询概念
      • 二、标量/单行子查询、列子/表子查询
      • 三、总结

一、子查询概念

子查询指一个查询语句嵌套在另一个查询语句内部的查询,这个特性从MySQL 4.1开始引入;在特定情况下,一个查询语句的条件需要另一个查询语句来获取,内层查询(inner query)语句的查询结果,可以为外层查询(outer query)语句提供查询条件。

内层查询即子查询,外层查询即主查询,只是叫法不同而已

查询需求:

查询公司中工资最低的员工信息

工资最低是多少?

SELECT * FROM emp WHERE sal=(SELECT MIN(sal) FROM emp); 

子查询规范:

  • 子查询必须放在小括号中
  • 子查询一般放在比较操作符的右边,以增强代码可读性
  • 子查询可以出现在几乎所有的SELECT字句中(如:SELECT、FROM、WHERE、ORDER BY、HAVING子句

子查询分类:

  1. 根据子查询返回的数据分类:

    • 标量子查询(scalar subquery):返回1行1列一个值

    • 行子查询(row subquery):返回的结果集是 1 行 N 列

    • 列子查询(column subquery):返回的结果集是 N 行 1列

    • 表子查询(table subquery):返回的结果集是 N 行 N 列

      子查询可以返回一个标量(就一个值)、一个行、一个列或一个表,这些子查询分别称之为标量、行、列和表子查询。

  2. 根据子查询和主查询之间是否有条件关联分类:

    • 相关子查询:两个查询之间有一定的条件关联(相互联系)
    • 不相关子查询:两个查询之间没有条件关联(相互独立)
  3. 为了方便,对于在何处使用子查询给大家给出几点个人建议:

    • 子查询出现在WHERE子句中:此时子查询返回的结果一般都是单列单行、单行多列、多行单列
    • 子查询出现在HAVING子句中:此时子查询返回的都是单行单列数据,同时为了使用统计函数操作
    • 子查询出现在FROM子句中:此时子查询返回的结果图一般都是多行多列,可以按照一张数据表(临时表)的形式操作

二、标量/单行子查询、列子/表子查询

✨✨标量子查询

子查询返回的是单行单列的数据,就是一个值

  • 查询出基本工资比ALLEN低的全部员工信息
SELECT * FROM emp WHERE sal<(SELECT sal FROM emp WHERE eanme='ALLEN');
  • 查询基本工资高于公司平均工资的全部员工信息
SELECT * FROM emp WHERE sal>(SELECT AVG(sal) FROM emp);
  • 查询出与ALLEN从事同一工作,并且基本工资高于员工编号为7521的全部员工信息
SELECT * FROM emp WHERE job=(SELECT job FROM emp WHERE ename='ALLEN') 
AND sal>(SELECT sal FROM emp WHERE empno=7521)
#把ALLEN自己去掉
AND ename<>'ALLEN';

效果如下:

在这里插入图片描述

✨✨单行子查询

子查询返回的是单行多列的数据,就是一条记录

  • 查询与SCOTT从事统一工作且工资相同的员工信息
SELECT * FROM emp WHERE (job,sal)=(SELECT job,sal FROM emp WHERE ename='SCOTT')
AND ename<>'SCOTT';
  • 查询与员工编号为7566从事统一工作且领导相同的全部员工信息
SELECT * FROM emp WHERE (job,mgr)=(SELECT job,mgr FROM emp WHERE empno=7566)
AND emp<>7566;

效果如下:
在这里插入图片描述

✨✨列子查询(多行子查询)

子查询返回的是多行单列的数据,就是一列数据。多行子查询也称为集合比较子查询,

在使用多行子查询需要使用多行比较操作符:

操作符含义
IN等于列表中的任意一个
ANY需要和单行比较操作符一起使用(>、<、=、<>…),与子查询结果中任何一个值比较,一个成立
ALL需要和单行比较操作符一起使用(>、<、=、<>…),和子查询返回的所有值比较,同时成立
SOME实际上是ANY的别名,作用相同,一般用ANY
  • IN操作符

    IN 运算符用来判断表达式的值是否位于给出的列表中;如果是,返回值为 1,否则返回值为 0。

    NOT IN 的作用和 IN 恰好相反,NOT IN 用来判断表达式的值是否不存在于给出的列表中;如果不是,返回值为 1,否则返回值为 0。

    • 查询出与每个部门中最低工资相同的员工信息
      • 按照部门分组,统计每个部门的最低工资
      • 根据最低工资查询出员工信息
SELECT * FROM emp WHERE sal IN(SELECT MIN(sal) FROM emp GROUP BY deptno)
AND deptno IS NOT NULL;
  • ANY操作符

    ANY关键字是一个MySQL运算符,如果子查询条件中ANY的比较结果为TRUE,则它会返回布尔值TRUE

    • 查询工资比任何管理工资都要高的员工信息
      • 查找出每个管理的薪资
      • 每个员工的薪资与每个管理的薪资比较
SELECT * FROM emp WHERE sal >ANY(
SELECT MIN(sal) FROM emp WHERE job='MANAGER' GROUP BY deptno);
  • ALL操作符

    ALL关键字是一个MySQL运算符,如果子查询条件中ALL的比较结果为TRUE,则它会返回布尔值TRUE

    • 案例同ANY操作符

效果如下:

在这里插入图片描述

✨✨表子查询

子查询返回的是多行多列的数据,就是一个表格
必须使用 IN、ANY 和 ALL 操作符对子查询返回的结果进行比较

综合练习:

  • 在emp表中,得到与10号部门任何一个员工入职年份和领导相同的员工信息(用在where子句中)
    • 需要用到DATE_FORMAT(hiredate,'%Y')将入职日期转换为年份
SELECT * FROM emp
WHERE (DATE_FORMAT(hiredate,'%Y'),mgr) IN (SELECT DATE_FORMAT(hiredate,'%Y') hiryear,mgr FROM emp WHERE deptno=10);

在这里插入图片描述

  • 查询出每个部门的编号、名称、位置、部门人数、平均工资(用在from子句中)
    • 以前学的多表联合查询——-emp、dept
    • 用子查询联合查询
SELECT d.deptno,d.dname,d.loc,COUNT(e.deptno),ROUND(AVG(sal),2) FROM
dept d LEFT JOIN emp e
ON e.deptno=d.deptno
GROUP BY d.deptno,d.dname,d.loc;

SELECT dept.deptno,dept.dname,dept.loc,d.count,d.avgsal FROM dept LEFT JOIN 
(SELECT deptno,COUNT(*) count,AVG(sal) avgsal  FROM emp GROUP BY deptno) d
ON dept.deptno=d.deptno;

在这里插入图片描述

  • 查询出所有在’SALES’部门工作的员工编号、姓名、基本工资、奖金、职位、雇佣日期、部门的最高和最低工资。(where和from子句同时使用)
#1
SELECT e.empno,e.ename,e.sal,e.comm,e.job,e.hiredate,minsal,maxsal,e.deptno  
FROM emp e JOIN 
(SELECT deptno,MIN(sal) minsal,MAX(sal) maxsal FROM emp GROUP BY deptno) td
ON e.deptno=td.deptno AND e.deptno=(SELECT deptno FROM dept WHERE dname='SALES');

#2
SELECT e.empno,e.ename,e.sal,e.comm,e.job,e.hiredate,minsal,maxsal,e.deptno  
FROM emp e JOIN 
(SELECT deptno,MIN(sal) minsal,MAX(sal) maxsal FROM emp GROUP BY deptno
HAVING deptno=(SELECT deptno FROM dept WHERE dname='SALES')) td
ON e.deptno=td.deptno;

在这里插入图片描述

  • 查询出比‘ALLEN’或‘CLACRK’薪资多的所有员工的编号、姓名、基本工资、部门名称、领导姓名、部门人数。
#隐式方式
SELECT e.empno,e.ename,e.sal,d.dname,me.ename 领导,temp.count FROM emp e,dept d,emp me,
(SELECT deptno,COUNT(deptno) count FROM emp e GROUP BY deptno) temp
WHERE e.deptno=d.deptno AND e.mgr=me.empno AND temp.deptno=e.deptno
AND e.sal >ANY(SELECT sal FROM emp WHERE ename IN('ALLEN','CLARK'))
AND e.ename NOT IN('ALLEN','CLARK');

#显示方式
SELECT e.empno,e.ename,e.sal,d.dname,me.ename 领导,temp.count 
FROM emp e 
JOIN dept d ON e.deptno=d.deptno
LEFT JOIN emp me ON e.mgr=me.empno
JOIN (SELECT deptno,COUNT(deptno) count FROM emp e GROUP BY deptno) temp ON temp.deptno=e.deptno
AND e.sal >ANY(SELECT sal FROM emp WHERE ename IN('ALLEN','CLARK'))
AND e.ename NOT IN('ALLEN','CLARK');

在这里插入图片描述

  • 列出公司各个部门的经理(假设每个部门只有一个经理,job为‘MANAGER’)的姓名、薪资、部门名称、部门人数、部门平均工资。
#隐式方式
SELECT e.ename,e.sal,d.dname,temp.count,temp.avgsal
FROM emp e,dept d,(SELECT deptno, COUNT(deptno) count,AVG(sal) avgsal FROM emp GROUP BY deptno) temp
 WHERE job='MANAGER' AND e.deptno=d.deptno AND temp.deptno=e.deptno;
 
 #显示方式
SELECT e.ename,e.sal,d.dname,temp.count,temp.avgsal
FROM emp e 
JOIN dept d ON e.deptno=d.deptno 
JOIN (SELECT deptno, COUNT(deptno) count,AVG(sal) avgsal FROM emp GROUP BY deptno) temp ON temp.deptno=e.deptno
 AND job='MANAGER';

在这里插入图片描述

  • 查询出所有薪资高于公司平均薪资的员工编号、姓名、基本工资、职位、雇佣日期、所在部门名称、部门位置、上级领导姓名、工资等级、部门人数、平均工资、平均服务年限。
#隐式方式
SELECT e.empno,e.ename,e.sal,e.job,e.hiredate,d.dname,d.loc,me.ename 领导,s.grade,temp.count,temp.avgsal,temp.avgyear
FROM emp e,dept d,emp me,salgrade s,(SELECT deptno,COUNT(deptno) count,AVG(sal) avgsal,AVG(TIMESTAMPDIFF(MONTH,hiredate,CURDATE())/12) avgyear FROM emp GROUP BY deptno) temp 
WHERE e.deptno=d.deptno AND e.sal>(SELECT AVG(sal) FROM emp)
AND e.mgr=me.empno
AND e.sal BETWEEN s.losal AND s.hisal
AND temp.deptno=e.deptno;

#显示方式
SELECT e.empno,e.ename,e.sal,e.job,e.hiredate,d.dname,d.loc,me.ename 领导,s.grade,temp.count,temp.avgsal,temp.avgyear
FROM emp e 
JOIN dept d ON e.deptno=d.deptno AND e.sal>(SELECT AVG(sal) FROM emp)
LEFT JOIN emp me ON e.mgr=me.empno
JOIN salgrade s ON e.sal BETWEEN s.losal AND s.hisal
JOIN (SELECT deptno,COUNT(deptno) count,AVG(sal) avgsal,AVG(TIMESTAMPDIFF(MONTH,hiredate,CURDATE())/12) avgyear FROM emp GROUP BY deptno) temp ON temp.deptno=e.deptno;

在这里插入图片描述

三、总结

  • ✨✨ 子查询允许结构化的查询,这样就可以把一个查询语句的每个部分隔开。
  • ✨✨子查询提供了另一种方法来执行有些需要复杂的join和union来实现的操作。
  • ✨✨在许多人看来,子查询可读性较高。 而实际上,这也是子查询的由来。

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

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

相关文章

MySQL - 第7节 - MySQL内置函数

1.日期函数 1.1.常用的日期函数 常用的日期函数如下&#xff1a; 1.2.current_date函数 current_date函数用于获取当前的日期。如下&#xff1a; 1.3.current_time函数 current_time函数用于获取当前的时间。如下&#xff1a; 1.4.current_timestamp函数 current_timestamp函数…

计组:各硬件工作原理

目录 ​编辑程序指令执行流程 程序执行指令前 执行各指令的顺序 程序&#xff08;每一条&#xff09;指令执行具体步骤 以第一步为例&#xff1a; 取指令&#xff08;#1~#4&#xff09; 初&#xff1a;&#xff08;PC)0&#xff0c;指向第一条指令的存储地址 #1&#x…

计算机组成原理学习笔记(学习中)

计算机系统概论 1.1计算机基本组成 冯诺依曼计算机特点&#xff1a; 计算机由五大部件组成&#xff1a;控制器&#xff0c;运算器&#xff0c;存储器&#xff0c;输入设备&#xff0c;输出设备 指令和数据以同等地位存于存储器&#xff0c;可按地址寻访 指令和数据用二进制…

一文读懂CAN总线及通信协议

CAN总线的汽车 CAN概念 CAN是控制器域网 (Controller Area Network, CAN) 的简称&#xff0c;是由研发和生产汽车电子产品著称的德国BOSCH公司开发了的&#xff0c;并最终成为国际标准&#xff08;ISO11898&#xff09;&#xff0c;是ISO国际标准化的串行通信协议。是国际上应…

Anchor-free应用一览:目标检测、实例分割、多目标跟踪

作者&#xff5c;杨阳知乎 来源&#xff5c;https://zhuanlan.zhihu.com/p/163266388 本文整理了与Anchor free相关的一些工作。一方面是分享近期在目标检测领域中一些工作&#xff0c;另一方面&#xff0c;和大家一起梳理一下非常火热的网络模型CenterNet、FCOS&#xff0c;当…

Linux网络-数据链路层,MAC帧解析

目录 数据链路层VS网络层 以太网概念 以太网的帧格式&#xff08;报文格式&#xff09;&#xff08;也可以称之为MAC帧&#xff09; MAC地址的概念 MAC帧格式 局域网通信原理 MTU MTU说明 MTU对IP协议的影响 MTU对UDP协议的影响 MTU对TCP协议的影响 数据链路层VS网…

【Linux】应用层协议:HTTP和HTTPS

每个人都可以很喜欢每个人&#xff0c;但喜欢治不了病&#xff0c;喜欢买不了东西&#xff0c;喜欢不能当饭吃&#xff0c;喜欢很廉价… 文章目录 一、HTTP协议1.URL1.1 URL的组成1.2 urlencode && urldecode 2.HTTP协议格式2.1 http请求和响应的格式2.2 通过代码来进行…

[Eigen中文文档] 求解稀疏线性系统

文档总目录 本文目录 稀疏求解器列表内置直接求解器内置迭代求解器外部求解器的包装器 稀疏求解器概念计算步骤基准测试例程 英文原文(Solving Sparse Linear Systems) 在Eigen中&#xff0c;有多种方法可用于求解稀疏系数矩阵的线性系统。由于此类矩阵的特殊表示&#xff0c…

零基础速成simulink代码生成——结合CANOE的DBC文件CAN报文代码生成 移植到硬件4

零基础速成simulink代码生成——结合CANOE的DBC文件CAN报文代码生成 移植到硬件4 本次我们将讲解如何将代码放到嵌入式硬件上运行,本次例子将dbc文件导入simulink中,生成代码,不需要我们自己实现数据库的内容。 导入DBC文件 新建一个simulink模型 MCU_CAN.slx simulink具…

开源计算机视觉库OpenCV详解

目录 1、概述 2、OpenCV详细介绍 2.1、OpenCV的起源 2.2、OpenCV开发语言 2.3、OpenCV的应用领域 3、OpenCV模块划分 4、OpenCV源码文件结构 4.1、根目录介绍 4.2、常用模块介绍 4.3、CUDA加速模块 5、OpenCV配置以及Visual Studio使用OpenCV 6、OpenCV和OpenGL的区…

SpringBoot常用操作

SpringBoot常用操作 SpringBoot启动过程 1. 生成一个SpringApplication的对象1. webApplicationType 推测web应用类型&#xff08;NONE、REACTIVE、SERVLET&#xff09;2. 从spring.factories中获取BootstrapRegistryInitializer对象3. initializers 从spring.factories中获…

A brief taste of JIFA

JIFA 是阿里贡献给 Eclipse 的一个适用于 Java 应用的问题诊断应用。 它以图形化的方式展示 Heap Dump AnalysisGC Log AnalysisThread Dump Analysis 因为云环境/生产环境的一些限制&#xff0c;应用的问题可能不能被就地分析&#xff0c;所以Jifa provides a web solution…

关于运动模糊问题的分析及处理方法

1、问题背景 前段时间有做一个化妆镜项目&#xff0c;就是一面镜子上装有一个摄像头&#xff0c;用户对着镜子化妆时&#xff0c;可同时用来采集人脸信息&#xff0c;分析人脸用的。客户反馈抓拍静止的人脸图像时&#xff0c;画面正常&#xff0c;而当人脸稍微运动时&#xff…

java springboot整合MyBatis实现分页查询以及带条件的分页查询

之前的文章 java springboot整合MyBatis做数据库查询操作操作了springboot整合MyBatis&#xff0c;然后简单做了个按id查询的操作 那么 我们按上文搭建起的环境继续 我们直接在staffDao接口中声明一个分页函数 Select("select * from staff limit #{page},#{pageSize}&q…

【Vue】Vite 组件化开发

文章目录 组件化开发一、组件化开发思想二、Vue 组件的构成2.1 组件组成结构2.2 组件 template 节点2.2.1 在 template 中使用指令2.2.2 在 template 中定义根节点 2.3 组件的 script 模板 三、组件的基本使用3.1 组件的注册3.1.1 全局组件注册3.1.2 局部组件注册 3.2 组件样式…

ffmpeg命令参数

主要参数 -i 设定输入流 -f 设定输出格式&#xff08;format&#xff09; -ss 开始时间 -t 时间长度视频参数 -vframes 设置要输出的视频帧数 -b 设定视频码率 -b:v 视频码率 -r 设定帧率 -s 设定画面的宽与高 -vn 不处理视频 -aspect aspect 设置横纵比4:3 或16:9 或1.333或…

软件项目管理 第三章软件项目的启动过程课后习题参考答案——主编:李冰、张桥珍、刘玉娥

第三章 软件项目的启动过程 课后习题参考答案 1.选择题 &#xff08;1&#xff09;乙方在项目初始阶段的主要任务不包含以下哪一项&#xff08;D&#xff09;。 A. 项目分析 B. 竞标 C. 合同签署 D. 合同管理 &#xff08;2&#xff09;项目章程中不…

Spring Boot Configuration Annotation Processor not configured 问题解决

目录 问题抛出&#xff1a; ConfigurationProperties 问题抛出&#xff1a; 进行Spring Boot配置文件部署时&#xff0c;发出警告Spring Boot Configuration Annotation Processor not configured&#xff0c;但是不影响运行。 不过有时候springboot项目出错了并且排除了所有…

【裸机开发】中断系统 —— 中断向量表(设置中断向量偏移的原因)

之前的LED驱动不存在中断&#xff0c;也就不包含中断的初始化。如果程序包含了中断&#xff0c;我们应还需要初始化哪些内容&#xff1f;要解决这个问题&#xff0c;我们需要先了解一个中断系统包含了哪些内容。 ① 中断向量表&#xff1a;描述中断对应的中断服务函数&#xf…

C++笔记之stack、queue、priority_queue、deque

code review! C笔记之stack、queue、priority_queue、deque 文章目录 C笔记之stack、queue、priority_queue、deque一.cppreference介绍1.stack2.queue3.priority_queue4.deque 二.容器适配器三.stack详解1.创建一个不包含任何元素的 stack 适配器&#xff0c;并采用默认的 de…