【Mysql】复合查询

news2024/11/27 10:33:16

文章目录

  • **1.基本查询回顾**
  • **2.多表查询** (重要)
      • 多表查询步骤
  • **3.自连接**
  • 4.子查询
    • 在from子句中使用子查询
  • 5.合并查询

1.基本查询回顾

准备工作,创建一个雇员信息表:(来自oracle 9i的经典测试表)

  • EMP员工表 DEPT部门表 SALGRADE工资等级表

image-20221019195007702


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

第一步:查询工资高于500或者岗位为MANAGER的雇员

image-20221021194636657

第二步:在上面筛选之后的条件下:还要满足姓名首字母为大写的J的雇员 ,此时需要利用到substring截取字符,判断第一个字符是否是j

image-20221021194622724

substring(ename,1,1) :从第1个字符开始往后截取,截取1个字符, 得到的就是姓名的首字母, (因为默认从1开始

案例2:按照部门号升序而雇员的工资降序排序

默认的order by 排序就是升序的(asc), 如果想要降序:desc

image-20221021194902982

先按部门号排序, 部门号相同的按照工资降序排序

案例3:使用年薪进行降序排序

第一步:先算出每个人的年薪, 年薪=工资*12 + 奖金, 但是我们可以发现,有的人是没有奖金的,其奖金为NULL

所以这里我们可以使用ifnull函数

  • IFNULL() 函数用于判断第一个表达式是否为 NULL,如果为 NULL 则返回第二个参数的值,如果不为 NULL 则返回第一个参数的值
  • ifnull(奖金,0) :如果奖金选项不是空,就返回0, 否则返回奖金

image-20221021195332225

第二步:按照年薪降序排序 , 因为此时是已经拿到了数据之后才能进行排序, 所以排序的地方可以使用别名

image-20221021195439784

案例4:显示工资最高的员工的名字和工作岗位

写法1:先拿到公司最高工资, 可能多个人的工资都是最高工资, 然后按照这个最高工资进行筛选人

image-20221021195705885

写法2:可以直接使用子查询, select里面套select, 先执行后面的子查询,它的执行结果作为下一个select的查询条件

image-20221021200106471

案例5:显示工资高于平均工资的员工信息

方法1:先拿到平均工资,然后按照这个平均工资进行筛选人

image-20221021200418110

方法2:使用子查询

image-20221021200513272

案例6:显示每个部门的平均工资和最高工资

做法:首先需要对每个部门做分组,然后求出每个部门的平均工资和最高工资

image-20221021201233987

  • 先从员工表emp当中拿到数据,然后按照部门编号deptno做分组, 然后针对每一组聚合求平均工资和最高工资

当然了,如果我们想平均工资只显示后面的2位小数: 可以使用format聚合函数控制格式: 四舍五入

image-20221021201358760

案例7:显示平均工资低于2000的部门号和它的平均工资

含义就是:先把平均工资低于2000的部门,然后求出这个部门的平均工资

做法:先分组,再聚合求出每一组的平均工资, 然后再按条件:,注意:这里不能使用where,可以使用having

image-20221021202524803

  • 不能使用where的原因:按照平均工资进行筛选的前提是:我们已经把每一组的平均工资算出来了,也就是我们的聚合操作已经完成了, 数据已经被提取出来了, 而where是在筛选数据的阶段帮我们对数据进行筛选的,是在分组前进行的, 我们这里已经把数据筛选出来做了分组了
  • 执行顺序:from -> where -> group by ->having -> select -> distinct -> order by -> limit

关于where, group by having

**where:**数据库中常用的是where关键字,用于在初始表中筛选查询

**group by:**对select查询出来的结果集按照某个字段或者表达式进行分组,获得一组组的集合

**having:**用于对where和group by查询出来的分组进行过滤,查出满足条件的分组结果


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

做法:先按照岗位进行分组,然后对每一组数据进行分组聚合

image-20221021202701326


2.多表查询 (重要)

实际开发中往往数据来自不同的表,所以需要多表查询

例子:emp表和dept表进行联合查询:

image-20221021202906941

什么叫笛卡尔积:

简单来说:就是排列组合, 把两张表的记录放在一起进行排列组合的所有情况, 全排列!一般而言,我们所进行的后续多表查询,都应该是笛卡尔积形成的新表的子集

  • 笛卡尔积的列数就是两个表的列数之和,行数则是两个表的行数之积,我们在进行多表查询的时候(计算笛卡尔积的过程),如果两个表数据很大,就会非常低效

如果是三个表的话,那么就是先将两个表进行笛卡尔积运算,再用这个表与另外一个表进行笛卡尔积操作


因为毕竟笛卡尔积只是简单的将他们进行排列组合(并没有进行筛选有效信息,我们将有效信息这一筛选的过程称为:连接条件 ,通常是存在 主外键约束 条件的多表建立的, 连接条件中两个字段通过 = 建立等值关系, 例如上面的例子当中, 连接条件就是: emp.deptno = dept.deptno

需要注意的是:笛卡尔积之后的新表,如果有相同的列名,就要通过表名.列名的方式区分,如果不用则会报错

  • 即:当多表查询有重名的列时,必须在列名前加上表名【一般用别名】作为前缀

如何看待多表查询:

我们认为,在我心中永远只有一张表,将来所有的多表查询都可以认为是单表查询, 我们认为select查询出来的"记录",都可以把它看作"表"

多表查询步骤

  1. 先把多表查询转化为单表查询
  2. 筛去排列组合产生的无意义数据
  3. 然后再根据要求进一步筛选
  4. 选定好需要展示的字段

案例1:显示雇员名,雇员工资以及所在部门的名字

雇员名,工资在emp表里面有,而部门的名字只在dept表里面有,上面的数据来自EMP和DEPT表,因此要进行多表查询

image-20221021203936321

我们首先需要根据emp表的外键deptno和主表dept的key做级联 -> 过滤非法数据,

image-20221021204116654

需要注意的是:如果合并之后,列名在表结构当中唯一存在,就可以直接使用,如果不是唯一存在,就在前面加一个列名表示使用的是原来那一张表的 表名.列名

image-20221021204443068

案例2:显示部门号为10的部门名,员工名和工资

员工名和工资在员工表里面有, 部门名只在部门表有,所以需要进行多表查询

做法:把两个表进行笛卡尔积,把数据穷举到一起, 然后根据连接条件:员工表的部门编号=部门表的编号, 把合法数据筛选出来, 然后根据条件筛选数据

image-20221021210127247

  • 注意:笛卡尔积之后的表,deptno列名不唯一,所以需要指定表名访问

案例3:显示各个员工的姓名,工资,及工资级别

工资级别 :在工资表, 员工的姓名和工资:在员工表 所以这里是多表查询

image-20221021212405617

问:此时什么是非法的数据? 工资不在对应的等级范围!

做法:先根据工资判断其是否在[losal,hisal]范围内,如果在,说明就是合法数据,否则是非法数据,

image-20221021212705956

因为此处sal losal hisal都是笛卡尔积之后的新表当中唯一的列名,所以不需要带表名区分


我们可以发现:上面多表查询做题的精髓是: 先确定要的数据在哪些表,然后把这些表进行笛卡尔积,整合在一起, 多表就变成了一张表, 然后再根据连接条件对数据做清洗,过滤掉非法的数据, 然后再按条件进行筛选


3.自连接

自连接是指在同一张表连接查询,一张表可以和别人笛卡尔积,当然也可以和自己笛卡尔,自连接时要对表名进行重命名,否则会出现名字冲突的问题.

  • 因为表名字不能相同,所以我们需要对表名取别名

image-20221021212926469

案例1:显示员工FORD的上级领导的编号和姓名

做法1:单表查询: 先找到这个员工FORD的领导的编号,然后根据编号找到这个领导是谁

image-20221021213356261

做法2:改成子查询 :先找到员工FORD的领导编号,然后用这个查出来的员工号,在员工表里面找这个编号

  • 也是单表查询

image-20221021213621642


做法3:多表查询,自连接

image-20221021213755256

因为笛卡尔积之后的表太大了,建立使用limit查询笛卡尔积之后的结果!, 这里因为自连接是两个同名字的表进行笛卡尔积,因为表名字不能相同,区分不开,需要取别名 把其中一张表起名为员工表,另一种为领导表

这里的连接条件是什么? 即:以什么条件过滤非法数据 员工表中自己的领导编号 = 领导表中自己的员工编号!

image-20221021214203056

  • 领导也是员工! (打工人) 这里的mgr就是员工对应的领导的编号, empno就是员工自己的编号

然后再根据条件筛选数据: 员工名字为’FORD’

image-20221021214429467

我们只要我们需要的数据:

image-20221021214509043

4.子查询

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询

1)单行子查询 (子查询的结果是单行)

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

案例1:显示SMITH同一部门的员工

做法1:先拿到SMITH的部门号,然后再在EMP表里面筛选在SMITH所属部门的员工

image-20221021215503115

做法2:直接写成子查询:

image-20221021215650169


案例2:显示工资最高的员工的名字和工作岗位

做法:最高工资的可能有一个或者多个, 先找出emp表中最高的工资,然后在查找时,找工资为最高工资的员工

image-20221021225433041

案例3:显示工资高于平均工资的员工信息

做法:先求出emp表中的平均工资,然后在查找时找工资高于平均工资的员工

image-20221021225552262


(2)多行子查询

多行子查询是指子查询的结果返回单列多行数据.

  • in关键字 :只要在多行单列的结果中,则条件满足.

案例:查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10号部门自己的员工

第一步:先拿到10号部门的岗位,如果有重复的话,还可以去重

image-20221021222049994

第二步:使用in关键字,在员工表当中找到在上面的这些岗位的人的信息

image-20221021222401033

第三步:再根据条件筛选:不包含10号部门自己的员工

image-20221021222454508

  • all关键字 :需要满足多行单列结果当中的所有,条件才满足

案例:显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号

第一步:先把30号部门的员工的工资列出来,可能存在相同的,要进行去重

image-20221021222754770

第二步:根据条件在员工表筛选: 比部门30的所有员工的工资高的员工

错误写法:

image-20221021222945244

原因:后面的select子查询得到的是多条的记录


正确写法:使用all ,因为选出的是比30号部门所有人工资都要高的员工,所以最后的结果肯定没有30号部门的人

image-20221021223041882


写法2:题目的本质其实就是找到工资>30号部门的最高工资的员工

image-20221021223255046

其实可以直接使用>,是因为后面子查询得到的只有一条记录


  • any 关键字 :只要满足多行单列结果当中的任一一个,则条件满足

案例:显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门的员工)

第一步:先拿出30号部门的员工的工资,可能存在相同的,要进行去重

select distinct sal from emp where deptno=30

第二步:找出比30号部门任意一个员工工资都要高的人, 此时需要使用any关键字

image-20221021223724235


如果此时还要加上一个条件:要在20号部门当中选出呢?

image-20221021223955874


写法2:题目的本质其实就是找到工资>30号部门的最低工资的员工

image-20221021223848784

所以30号部门的人也会被显示上


in:我是否属于你们的一员 all:我比你们都怎么样 any:我比你们任意一个人怎么样


(3)多列子查询

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

案例:查询和SMITH这个员工的部门和岗位完全相同的所有雇员,不含SMITH本人

第一步:先拿到SMITH的部门和岗位,

image-20221021224324320

我们需要同时找到deptno和job两列数据,上面的多行子查询都只是包含一列数据, 此时得到的是单行多列的数据

第二步:进行筛选:,前面的得到的就是和SMITH在同一个部门同一个岗位的人, 然后用and条件再把SMITH筛选走

image-20221021224649459

可以认为,()就是表示MySQL内部实现的集合

在from子句中使用子查询

子查询语句出现在from子句中,这里要用到数据查询的技巧,把一个子查询当做一个临时表使用

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

做法:要拿自己员工表的工资和平均工资作比较, 首先需要分组求出每个部门的平均工资

image-20221022093936985

可以把上面查到的内容当成一张表,它里面放着就是部门和它的平均工资,然后把这张表和员工表做笛卡尔积

image-20221022094139426

然后再过滤出非法的数据, 必须保证:员工的部门编号=平均工资表的部门编号才有意义, 子查询是先被执行的,先有的avg_tb表,然后才进行非法数据过滤,所以可以用别名

  • 因为笛卡尔积穷举的时候,有多信息是无效的,需要进行过滤 部门号匹配的才是有效数据

image-20221022094336123

然后再根据条件筛选:员工的工资要比它所在部门的工资高 就是拿员工表的工资和平均工资表的平均工资比较,筛选出工资要高于自己部门平均工资的员工

image-20221022094601787

我们只想要某些信息:

image-20221022094754337


在上面的基础上.如果我们想把部门也显示出来呢?

把上面的表和部门表dept做笛卡尔积!然后再根据部门号要相等进行非法数据过滤

image-20221022095638591

案例2:查找每个部门工资最高的人的姓名、工资、部门、最高工资

先根据部门号分组,求出每个部门的最高工资,然后形成的这张表和员工表进行笛卡尔积, 根据 员工表的部门编号=最高工资表的部门编号进行过滤非法数据, 然后找到每个部门工资最高的人,可能有1个或者多个 (只要员工的工资=部门表的最高工资,该员工就是它部门的最高工资的人)

image-20221022100336868

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

第一步:先根据部门分组,统计每个部门的人数->需要使用count函数,然后得到的内容作为新表 和部门表做笛卡尔积, 根据: 新表的部门编号=部门表的部门编号进行过滤非法数据, 然后需要什么信息就显示什么信息

image-20221022100929604


做法2:直接把员工表和部门表做笛卡尔积, 然后根据部门编号要相同过滤非法数据, 然后按照部门进行分组,需要什么就显示什么

image-20221022101638091


5.合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all

1)union 该操作符用于取得两个结果集的并集,当使用该操作符时,会自动去掉结果集中的重复行,

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

工资和职位的信息都早员工表里面有,所以就是单表查询

写法1:直接根据条件在员工表进行筛选

image-20221022101806300

写法2:求两个表的并集

image-20221022102056340

2)union all 该操作符用于取得两个结果集的并集,当使用该操作符时,不会去掉结果集中的重复行,

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

image-20221022102503338


信息列必须一样,否则会出问题

image-20221022102931787


关键字解释
union取并集,将多个 select 结果合并到一起,自动去掉重复行
union all取并集,将多个 select 结果合并到一起,但不去重

总结:

  • 子查询可以出现在两个地方(常规,重要)
  • 1. where字句中,作为筛选条件使用
  • 2. from字句中,用来和特定的表做笛卡尔积

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

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

相关文章

SVN+Gitee配置版本控制库

软件 TortoiseSVN:Downloads TortoiseSVN Gitee:https://gitee.com/ 操作步骤 在Gitee中新建仓库,设置仓库名以及模板(Readme文件); 启用SVN访问 在仓库的管理页面,选择“功能设置”中的“…

为自己量身打造一个 Rust 项目模板/脚手架

摘要 quick-start-rs(quick start a rust project)是用于快速创建一个 rust 项目的脚手架/模板。 标题:为自己量身打造一个 Rust 项目模板/脚手架深度参考 Rust Code Quick Start文章来自 suhanyujieTags: Rust, utils, quick start, project template,脚…

视频编解码 — 带宽预测

目录 一、带宽预测作用 二、基于延时的带宽预测算法: 1、算法流程 2、计算延时 3、Trendline Filter 4、网络状态判断 5、带宽调整更新 三、基于丢包的带宽预测算法 1、带宽调整 四、最大带宽探测算法 五、最终的预测选择 一、带宽预测作用 控制音视频发…

荧光AF染料477876-64-5,Alexa Fluor 532,AF532 NHS ester

●中文名:AF532 活性酯,AF5 532酯 ●英文名:AF532-NHS ,AF532 NHS ester,Alexa Fluor 532 ●外观以及性质: 荧光AF染料是具有磺化基团的荧光物质。AF染料带负电荷,具有亲水性高、亮度高、光稳定…

软件和硬件中的调用

文章目录**1 概述****2.1 程序进程内的调用:函数调用****2.2 程序进程间的调用:IPC****2.3 远程程序调用:RPC****2.4 远程调用REST****3 硬件“调用”****3.1 综述****总线模型****3.2 片内的总线****3.3 Chiplet多DIE封装互联总线****3.4 板…

1.1 统计学习方法的定义与分类

统计学习方法的定义与分类统计学习的概念统计学习的定义统计学习运用到的领域统计学习的步骤统计学习的分类统计学习的概念 统计学习的定义 统计学习 (Statistical Machine Learning) 是关于计算机基于数据构建概率统计模型并运用模型对数据进行预测与分析的一门学科。 以计…

Python任务调度框架Rocketry

文章目录定时任务库对比简介与其余框架的区别安装初试调度器基础测试方法字符串格式具体时间间隔周期某时间段条件 API条件逻辑方法对比执行选项在主进程和线程中执行进程线程异步设置默认选项日志流水线在一个任务后执行输入作为输出会话级参数函数参数TODO:元参数…

为什么说继承是把双刃剑

为什么说继承是把双刃剑 继承其实是把双刃剑:一方面继承是非常强大的;另一方面继承的破坏力也是很强的。 继承广泛应用于各种Java API、框架和类库之中,一方面它们内部大量使用继承,另一方面它们设计了良好的框架结构&#xff0c…

20221130 RabbitMQ

MQ MQ(Message Queue)消息队列,是基础数据结构中“先进先出”的一种数据结构。一般用来解决应用解耦,异步消息,流量削峰等问题,实现高性能,高可用,可伸缩和最终一致性架构。 主要的…

【正点原子FPGA连载】第二十三章 DDS信号发生器实验摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0

1)实验平台:正点原子MPSoC开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id692450874670 3)全套实验源码手册视频下载地址: http://www.openedv.com/thread-340252-1-1.html 第二十三章 DDS信…

web网页设计期末课程大作业__公司官网 (曼谷科技 1页)带psd文件

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材,DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 家公司官网网站 | 企业官网 | 酒店官网 | 等网站的设计与制 | HTML期末大学生网页设计作业,Web大学生网页 HTML:结构 CSS&…

基于CCE Kubernetes网络与持久化存储实战

✅作者简介: CSDN内容合伙人,全栈领域新星创作者,阿里云专家博主,阿里云问答板块版主,华为云享专家博主,掘金后端评审团成员 💕前言: 最近云原生领域热火朝天,那么云原生…

2022年NPDP新版教材知识集锦--【第四章节】(4)

【初始设计与规格阶段】(全部获取文末) 产品设计规格旨在: 明确产品设计并提供量化和客观性; 将产品设计要求传达给设计团队的其他成员; 推进产品从设计到制造的开发。 1、功能性设计(DesignforFunctionality,DFF) 功能设计决定了产品的最终性能,功…

小猴吃苹果-第12届蓝桥杯Scratch选拔赛真题精选

[导读]:超平老师计划推出Scratch蓝桥杯真题解析100讲,这是超平老师解读Scratch蓝桥真题系列的第90讲。 蓝桥杯选拔赛每一届都要举行4~5次,和省赛、国赛相比,题目要简单不少,再加上篇幅有限,因此我精挑细选…

JCTC:基于PWmat中的混合溶剂模型精确计算离子溶解自由能

溶液环境中溶质离子或中间体的自由能计算是电化学研究中最棘手的问题之一。目前单纯的实验手段并不能对发生在溶液中的化学反应过程/机理进行直接探测,许多信息仍主要依赖于理论模拟。对于这一问题,目前很多研究者采用经验势场的溶剂模型方法&#xff0c…

Casein-PEG-Rhodamine B 络蛋白-聚乙二醇-罗丹明B Casein-RB

产品名称:络蛋白-聚乙二醇-罗丹明B 英文名称:Casein-PEG-Rhodamine B 质量控制:95% 原料分散系数PDI:≤1.05 存储条件:-20C,避光,避湿 用 途:仅供科研实验使用,不用于诊…

SAP 电商云 Spartacus UI Configurable Product 的页面设置

关键字 CPQ,Product Configuration,Product Configure,Product Variant 变体是在某些方面彼此不同但基于相同基本模型的产品。 变体的一个示例是 T 恤的颜色和尺寸。 在 Spartacus 中启用变体功能,并在 SAP Commerce Cloud 中配…

基于python的pulp库使用,从基础模型到复杂模型,从一维变量到二维变量

写在前面 学习笔记,仅作参考。 个人觉得配合步骤和建模,直接看代码就能入门pulp,所以没有啥解释,见谅。 参考 https://blog.csdn.net/youcans/article/details/116371416 步骤 1、安装PuLp (pip install pulp) 2…

HRD特征及其检测方法简介

HRD特征及其检测方法简介1、HRD背景知识介绍1.1 HRR通路简介1.2 HRR基因突变可导致通路失活和HRD1.3 HRD高发癌种2、HRD的两类主要标志物2.1 致病基因2.2 基因组瘢痕3、HRD检测方法4、全景变异分析(CGP)5、关键信息6、参考文件1、HRD背景知识介绍 1.1 H…

(4)点云数据处理学习——其它官网例子

1、主要参考 (1)视频,大佬讲的就是好啊 【Open3D】三维点云python教程_哔哩哔哩_bilibili (2)官方的github地址 GitHub - isl-org/Open3D: Open3D: A Modern Library for 3D Data Processing (3&#…