【MySQL系列】MySQL复合查询的学习 _ 多表查询 | 自连接 | 子查询 | 合并查询

「前言」文章内容大致是对MySQL复合查询的学习。

「归属专栏」MySQL

「主页链接」个人主页

「笔者」枫叶先生(fy)

MySQL

目录

  • 一、基本查询回顾
  • 二、多表查询
  • 三、自连接
  • 四、子查询
    • 4.1 单行子查询
    • 4.2 多行子查询
    • 4.3 多列子查询
    • 4.4 在from子句中使用子查询
  • 五、合并查询

一、基本查询回顾

前面篇章讲解的mysql表的查询都是对一张表进行查询,在实际开发中这远远不够,下面将讲解复合查询,首先回顾一下基本的查询。

使用的数据库是之前篇章的雇员信息表,员工表(emp)、部门表(dept)和工资等级表(salgrade)
在这里插入图片描述

查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J

mysql> select * from emp where (sal > 500 or job = 'MANAGER') and ename like 'J%';

在这里插入图片描述

按照部门号升序而雇员的工资降序排序

mysql> select * from emp order by deptno asc, sal desc;

在这里插入图片描述

使用年薪进行降序排序

mysql> select ename, sal*12+ifnull(comm, 0) as 年薪 from emp order by 年薪 desc;

在这里插入图片描述
注:

  • 由于NULL与任何值做计算得到的结果都是NULL,因此在计算年薪时不能直接用月薪的12倍加上每个员工的奖金,这样可能导致得到的年薪为NULL值。
  • 在计算每个员工的年薪时,应该通过ifnull函数判断员工的奖金是否为NULL,如果不为NULL则ifnull函数返回员工的奖金,如果为NULL则ifnull函数返回0,避免让NULL值参与计算

显示工资最高的员工的名字和工作岗位

解决该问题需要进行两次查询
在这里插入图片描述
此外,这种问题还可以使用子查询,将两句查询语句合并起来,需要将第一次查询的SQL语句用括号括起来。

mysql> select ename, job from emp where sal = (select max(sal) from emp);

在这里插入图片描述

显示工资高于平均工资的员工信息

也是使用子查询解决

mysql> select * from emp where sal > (select avg(sal) from emp);

在这里插入图片描述

显示每个部门的平均工资和最高工资

在group by子句中指明按照部门号进行分组,在select语句中使用avg函数和max函数,分别查询每个部门的平均工资和最高工资

mysql> select deptno, format(avg(sal), 2) 平均, max(sal) 最高 from emp group by deptno;

在这里插入图片描述

显示平均工资低于2000的部门号和它的平均工资

在group by子句中指明按照部门号进行分组,在select语句中使用avg函数查询每个部门的平均工资,在having子句中指明筛选条件为平均工资小于2000

mysql> select deptno, avg(sal) 平均工资 from emp group by deptno having 平均工资 < 2000;

在这里插入图片描述

显示每种岗位的雇员总数,平均工资

mysql> select job, count(*) 人数, format(avg(sal), 2) 平均工资 from emp group by job;

在这里插入图片描述

二、多表查询

上面的基础查询都是在一张表的基础上进行的查询,实际开发中往往数据来自不同的表,所以需要多表查询。

  • 在进行多表查询时,只需要将多张表的表名依次放到from子句之后,用逗号隔开即可,这时MySQL将会对给定的这多张表取笛卡尔积,作为多表查询的初始数据源
  • 多表查询的本质,就是对给定的多张表取笛卡尔积,然后在产生的新表进行查询

笛卡尔积是指给定两个集合A和B,其中A中的每个元素和B中的每个元素都可以组成一个有序对,这些有序对的集合就是A和B的笛卡尔积。

例如,员工表和部门表进行笛卡尔积

员工表:
在这里插入图片描述
部门表:
在这里插入图片描述
两张表进行笛卡尔积

mysql> select * from emp, dept;

在这里插入图片描述
员工表和部门表的笛卡尔积由两部分组成,前半部分是员工表的列信息,后半部分是部门表的列信息
在这里插入图片描述
对员工表和部门表取笛卡尔积时,会先从员工表中选出一条记录与部门表中的所有记录进行组合,然后再从员工表中选出一条记录与部门表中的所有记录进行组合,以此类推,最终得到一张新表
在这里插入图片描述
对多张表取笛卡尔积后得到的数据并不都是有意义的。

比如对员工表和部门表取笛卡尔积时,员工表中的每一个员工信息都会和部门表中的每一个部门信息进行组合,而实际一个员工只有和自己所在的部门信息进行组合才是有意义的,因此需要从笛卡尔积产生的新表筛选出员工的部门号和部门的编号相等记录。
在这里插入图片描述
注意:进行笛卡尔积的多张表中可能会存在相同的列名,这时在选中列名时需要通过表名.列名的方式进行指明,如果有重复的不指明确切一列,就会报错。
在这里插入图片描述

显示雇员名、雇员工资以及所在部门的名字

从题意可以看出,部门名只有dept表中才有,其他数据来源于emp表,即数据来自EMP和DEPT表,因此要联合查询,即多表查询

mysql> select emp.ename, emp.sal, dept.deptno from emp, dept where emp.deptno = dept.deptno;

在这里插入图片描述

显示部门号为10的部门名,员工名和工资

部门名只有部门表中才有,员工名和员工工资只有员工表中才有,因此需要同时使用员工表和部门表进行多表查询,在where子句中指明筛选条件为员工的部门号等于部门编号(筛选符合条件的信息)

mysql> select ename, sal, emp.deptno, dname from emp, dept where emp.deptno = dept.deptno and dept.deptno = 10;

在这里插入图片描述
注意:在筛选部门号等于10的部门时,可以使用员工表中的部门号,也可以使用部门表中的部门编号,因为两列都是一样的。

显示各个员工的姓名,工资,及工资级别

员工名和工资只有员工表中才有,而工资级别只有工资等级表中才有,因此需要同时使用员工表和工资等级表进行多表查询,在where子句中指明筛选条件为员工的工资在losal和hisal之间的记录

mysql> select ename, sal, grade from emp, salgrade where sal between losal and hisal;

在这里插入图片描述

三、自连接

自连接是指在同一张表进行连接查询,也就是说我们不仅可以对不同表进行取笛卡尔积,也可以对同一张表取笛卡尔积

显示员工FORD的上级领导的编号和姓名

可以使用子查询,先对员工表进行查询得到FORD的领导的编号,然后再根据领导的编号对员工表进行查询得到FORD领导的姓名

mysql> select empno, ename from emp where empno = (select mgr from emp where ename = 'FORD');

在这里插入图片描述
也可以使用多表查询(自查询),因为员工表中的mgr字段能够将表中员工的信息和员工领导的信息关联起来。

mysql> select leader.empno, leader.ename from emp leader, emp worder where leader.empno = worder.mgr and worder.ename = 'FORD';

在这里插入图片描述
由于自连接是对同一张表取笛卡尔积,因此在自连接时至少需要给一张表取别名,否则无法区分这两张表中的列。

四、子查询

  • 子查询是指嵌入在其他SQL语句中的查询语句,也叫嵌套查询
  • 子查询可分为单行子查询、多行子查询、多列子查询,以及在from子句中使用的子查询

4.1 单行子查询

单行子查询,是指返回单行单列数据的子查询

显示SMITH同一部门的员工

在子查询中查询SMITH所在的部门号,在where子句中指明筛选条件为员工部门号等于子查询返回的部门号

mysql> select * from emp where deptno = (select deptno from emp where ename = 'SMITH');

在这里插入图片描述
此外,解决该问题也可以使用自连接

4.2 多行子查询

多行子查询,是指返回多行单列数据的子查询

使用in关键字;查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自己的

先查询10号部门有哪些工作岗位,在查询时要对结果进行去重,因为10号部门的某些员工的工作岗位可能是相同的
在这里插入图片描述
然后将上述查询作为子查询,在查询员工表时在where子句中使用in关键字,in关键字用于判断员工的工作岗位是子查询得到的若干岗位中的一个


mysql> select ename, job, deptno from emp 
    -> where job in (select distinct job from emp where deptno=10) and deptno<>10;

在这里插入图片描述

实用all关键字;显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号

先查询30号部门员工的工资,进行去重
在这里插入图片描述

将上述查询作为子查询,在查询员工表时在where子句中使用all关键字,all关键字用于判断员工的工资是否高于子查询得到的所有工资

mysql> select ename, sal, deptno from emp where sal > all(select distinct sal from emp where deptno=20);

在这里插入图片描述

使用any关键字;显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门的员工)

先查询30号部门员工的工资,然后在查询员工表时在where子句中使用any关键字,判断员工的工资是否高于子查询的得到的工资中的某一个

mysql> select ename, sal, deptno from emp where sal > any(select distinct sal from emp where deptno=30);

在这里插入图片描述

4.3 多列子查询

单行子查询是指子查询只返回单列,单行数据;多行子查询是指返回单列多行数据,都是针对单列而言的,而多列子查询则是指查询返回多个列数据的子查询语句

查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人

先查询SMITH所在部门的部门号和他的岗位,然后将上述查询作为子查询

mysql> select * from emp where (deptno,job) = (select deptno, job from emp where ename = 'SMITH') and ename <> 'SMITH';

在这里插入图片描述
注:

  • 多列子查询得到的结果是多列数据,在比较多列数据时需要将待比较的多个列用圆括号括起来
  • 多列子查询返回的如果是多行数据,在筛选数据时也可以使用in、all和any关键字

4.4 在from子句中使用子查询

  • 子查询语句不仅可以出现在where子句中,也可以出现在from子句中
  • 子查询语句出现from子句中,其查询结果将会被当作一个临时表使用

显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资

先查询每个部门的平均工资,这张表当做临时表使用
在这里插入图片描述
然后对员工表和上述的查询结果进行多表查询,在where子句中指明筛选条件为员工的部门号等于临时表中的部门号,并且员工的工资大于临时表中的平均工资

mysql> select ename, emp.deptno, sal, 平均工资 from emp, (select deptno, avg(sal) 平均工资 from emp group by deptno) tmp 
    -> where emp.deptno=tmp.deptno and sal > 平均工资;

在这里插入图片描述
注意:在from子句中使用子查询时,必须给子查询得到的临时表取一个别名,否则查询将会出错

查找每个部门工资最高的人的姓名、工资、部门、最高工资

先查询每个部门的最高工资
在这里插入图片描述
然后对员工表和上述的查询结果进行取笛卡尔积,在where子句中指明筛选条件为员工的部门号等于临时表中的部门号,并且员工的工资等于临时表中的最高工资

mysql> select ename, sal, emp.deptno, 最高工资 from emp, (select max(sal) 最高工资, deptno from emp group by deptno) tmp 
    ->  where emp.deptno=tmp.deptno and sal=最高工资;

在这里插入图片描述

显示每个部门的信息(部门名,编号,地址)和人员数量

按照部门号进行分组,分别查询每个部门的人员数量
在这里插入图片描述
述查询作为子查询放在from子句中,然后对员工表和临时表取笛卡尔积,在where子句中指明筛选条件为员工的部门号等于临时表中的部门号即可

mysql> select dname, dept.deptno, loc, 部门人数 from dept, (select deptno, count(*) 部门人数 from emp group by deptno) 
    -> tmp where dept.deptno = tmp.deptno;

在这里插入图片描述
上述也可以只使用多表查询解决

mysql> select dname, dept.deptno, loc, count(*) 人数 from emp, dept 
    -> where emp.deptno = dept.deptno 
    -> group by dept.deptno, dname, loc;

在这里插入图片描述

五、合并查询

合并查询,是指将多个查询结果进行合并,关键字unionunion all

  • union用于取得两个查询结果的并集,union会自动去掉结果集中的重复行
  • union all也用于取得两个查询结果的并集,但union all不会去掉结果集中的重复行

将工资大于2500或职位是MANAGER的人找出来

查询工资大于2500的员工,查询职位是MANAGER的员工
在这里插入图片描述
可以使用or操作符将where子句中的两个条件关联起来
在这里插入图片描述
也可以使用union将上述的两条查询SQL连接起来,这时将会得到两次查询结果的并集,并且会对合并后的结果进行去重

mysql> select ename, job, sal from emp where sal > 2500 union
    -> select ename, job, sal from emp where sal > 2500 or job = 'MANAGER';

在这里插入图片描述
可以使用union all,结果是不去重
在这里插入图片描述
注意:待合并的两个查询结果的列的数量必须一致,否则无法合并
--------------------- END ----------------------

「 作者 」 枫叶先生
「 更新 」 2023.8.25
「 声明 」 余之才疏学浅,故所撰文疏漏难免,
          或有谬误或不准确之处,敬请读者批评指正。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解密算法与数据结构面试:程序员如何应对挑战

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

Windows版本Docker安装详细步骤

文章目录 下载地址安装异常处理docker desktop requires a newer wsl 下载地址 https://desktop.docker.com/win/stable/Docker%20Desktop%20Installer.exe 安装 双击下载的文件Docker Desktop Installer.exe进行安装 点击OK 开始安装 安装完成点击Close and restart&…

电脑不安装软件,怎么将手机文件传输到电脑?

很多人都知道&#xff0c;AirDroid有网页版&#xff08;web.airdroid.com&#xff09;。 想要文件传输&#xff0c;却不想在电脑安装软件时&#xff0c;AirDroid的网页版其实也可以传输文件。 然而&#xff0c;要将文件从手机传输文件到网页端所在的电脑时&#xff0c;如果按…

“惠医通-医院挂号订单平台”

结合已学习过的vue3和TS完成的项目&#xff0c;便于患者对自己想要就诊的科室进行挂号&#xff0c;付款 一&#xff1a;项目简介 前端技术栈 Vue3 TS vue-router Element-ui Axios Pinia 项目架构 二&#xff1a;主要模块 1. axios二次封装 1.1 创建实例 //利用axios.creat…

视频融合平台EasyCVR视频汇聚平台关于小区高空坠物安全实施应用方案设计

近年来&#xff0c;随着我国城市化建设的推进&#xff0c;高楼大厦越来越多&#xff0c;高空坠物导致的伤害也屡见不鲜&#xff0c;严重的影响到人们的生命安全。像在日常生活中一些不起眼的小东西如烟头、鸡蛋、果核、易拉罐&#xff0c;看似伤害不大&#xff0c;但只要降落的…

Go【gin和gorm框架】实现紧急事件登记的接口

简单来说&#xff0c;就是接受前端微信小程序发来的数据保存到数据库&#xff0c;这是我写的第二个接口&#xff0c;相比前一个要稍微简单一些&#xff0c;而且因为前端页面也是我写的&#xff0c;参数类型自然是无缝对接_ 前端页面大概长这个样子 先用apifox模拟发送请求测试…

①matlab的命令掌握

目录 输入命令 命名变量 保存和加载变量 使用内置的函数和常量 输入命令 1.您可以通过在命令行窗口中 MATLAB 提示符 (>>) 后输入命令 任务 使用命令 3*5 将数值 3 和 5 相乘。 答案 3*5 2.除非另有指定&#xff0c;否则 MATLAB 会将计算结果存储在一个名为 ans…

美团面试拷打:ConcurrentHashMap 为何不能插入 null?HashMap 为何可以?

周末的时候,有一位小伙伴提了一些关于 ConcurrentHashMap 的问题,都是他最近面试遇到的。原提问如下(星球原贴地址:https://t.zsxq.com/11jcuezQs ): 整个提问看着非常复杂,其实归纳来说就是两个问题: ConcurrentHashMap 为什么 key 和 value 不能为 null?ConcurrentH…

MongoDB Long 类型 shell 查询

场景 1、某数据ID为Long类型&#xff0c;JAVA 定义实体类 Id Long id 2、查询数据库&#xff0c;此数据存在 3、使用 shell 查询&#xff0c;查不到数据 4、JAVA代码查询Query.query 不受任何影响 分析 尝试解决&#xff08;一&#xff09; long 在 mongo中为 int64 类型…

clickhouse(十四、分布式DDL阻塞及同步阻塞问题)

文章目录 一、分布式ddl 阻塞、超时现象验证方法解决方案 二、副本同步阻塞现象验证解决方案 一、分布式ddl 阻塞、超时 现象 在clickhouse 集群的操作中&#xff0c;如果同时执行一些重量级变更语句&#xff0c;往往会引起阻塞。 一般是由于节点堆积过多耗时的ddl。然后抛出…

论文阅读:Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks

前言 要弄清MAML怎么做&#xff0c;为什么这么做&#xff0c;就要看懂这两张图。先说MAML**在做什么&#xff1f;**它是打着Mate-Learing的旗号干的是few-shot multi-task Learning的事情。具体而言就是想训练一个模型能够使用很少的新样本&#xff0c;快速适应新的任务。 定…

PCB电路板电压电流监测软件

PCB电路板电流监测软件详细设计说明书是一个详细描述软件系统设计和实现的文档&#xff0c;它提供了软件系统的架构、功能模块、接口设计、数据存储和处理、界面设计、数据库设计、系统测试、部署和维护计划等方面的详细信息。模拟量采集/老化房采集软件 该文档的目的是为了确保…

深入解析文件系统原理(inode,软硬链接区别)

第四阶段提升 时 间&#xff1a;2023年8月29日 参加人&#xff1a;全班人员 内 容&#xff1a; 深入解析文件系统原理 目录 一、Inode and Block概述 &#xff08;一&#xff09;查看文件的inode信息&#xff1a;stat &#xff08;二&#xff09;Atime、Mtime、Ctime详…

计算机网络aaaaaaa

差错检测 在一段时间内&#xff0c;传输错误的比特占所传输比特总数的比率称为误码率BER(Bit Error Rate) 11111111111111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111111…

「Vue|网页开发|前端开发」02 从单页面到多页面网站:使用路由实现网站多个页面的展示和跳转

本文主要介绍如何使用路由控制来实现将一个单页面网站扩展成多页面网站&#xff0c;包括页面扩展的逻辑&#xff0c;vue的官方路由vue-router的基本用法以及扩展用法 文章目录 本系列前文传送门一、场景说明二、基本的页面扩展页面扩展是在扩什么创建新页面的代码&#xff0c;…

Linux内核源码分析 (3)调度器的实现

Linux内核源码分析 (3)调度器的实现 文章目录 Linux内核源码分析 (3)调度器的实现一、概述二、调度器数据结构1、task_struct中与调度有关的的成员2、调度器类3、就绪队列4、调度实体 三、处理优先级1、优先级的内核表示2、计算优先级3、计算负荷权重 四、核心调度器1、周期性调…

网络安全(黑客技术)学习手册

1.网络安全是什么 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 2.网络安全市场 一、是市场需求量高&#xff1b; 二、则是发展相对成熟…

VBA技术资料MF48:VBA_在Excel中将列号与字母转换

【分享成果&#xff0c;随喜正能量】除非自己的认知获得了改变和刷新&#xff0c;否则&#xff0c;人们常说的“顺应自己的内心”&#xff0c;顺的不过是一颗旧心&#xff0c;一颗惯性的&#xff0c;充满了各种习性的套路之心。与“顺应自己的内心”恰恰相反&#xff0c;人要用…

自动化PLC工程师能否转到c#上位机开发?

成功从自动化PLC工程师转向C#上位机开发的经历可能因人而异&#xff0c;以下是一些分享的思路和建议&#xff1a;扩展编程技能&#xff1a;学习C#语言和相关的开发工具和框架&#xff0c;掌握语言的基础知识和常用的编程技巧。可以通过在线教程、培训课程、书籍等途径进行学习&…

c# modbus CRC计算器(查表法)

一、简介&#xff1a; 本案例为crc计算器&#xff0c;通过查表法计算出结果 1.窗体后台源代码 using Crc; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text…