【MySQL】--- 复合查询 内外连接
Welcome to 9ilk's Code World
(๑•́ ₃ •̀๑) 个人主页: 9ilk
(๑•́ ₃ •̀๑) 文章专栏: MySQL
🏠 基本查询回顾
假设有以下表结构:
-
查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J
思路 : 用两个条件对员工表进行筛选。条件1:工资高于500或岗位为MANAGER。条件2:姓名首字母为大写的J。条件1内为或关系,条件1和条件2为并联关系。
参考代码:
//like
select * from emp where (sal>500 or job='MANAGER') and ename like 'J%';
//子串
select * from emp where (sal>500 or job='MANAGER') and substring(ename,1,1)=='J'; //截取子串
测试结果:
- 按照部门号升序而雇员的工资降序排序
参考代码:
select * from emp order by deptno asc , sal desc; //asc升序 desc降序
测试结果:
- 使用年薪进行降序排序
员工表中的comm奖金字段可以为空,但是MySQL中NULL是不参与运算的,我们可以使用ifnull函数进行处理。
参考代码:
//奖金可以为空有的岗位没奖金 所以对这种情况可以使用ifnull 是null就第二个参数
select *,sal*12+ifnull(comm,0) 年薪 from emp;
测试结果:
- 显示工资最高的员工的名字和工作岗位
求最高可以使用排序也可以使用聚合函数。
参考代码:
select ename,job from emp order by sal desc limit 1;//排序
select ename, job from emp where sal = (select max(sal) from emp); //聚合函数子查询
测试结果:
注:MySQL允许在一条SQL内部再执行select查询,称为子查询!
- 显示工资高于平均工资的员工信息
思路:我们先需要知道员工表中所有员工的平均信息,然后在员工表中根据平均工资筛选员工信息。
参考代码:
select * from emp where sal > (select AVG(sal) from emp); //先聚合统计平均工资
测试结果:
- 显示每个部门的平均工资和最高工资
参考代码:
select deptno,AVG(sal),max(sal) from emp group by deptno;
//先分组 再聚合
测试结果:
- 显示平均工资低于2000的部门号和它的平均工资
思路“我们先根据部门进行分组,然后对每个组进行聚合取得平均工资,最后对分组之后的结果having进行筛选。
参考代码:
select deptno,AVG(sal)平均工资 from emp group by deptno having 平均工资 < 2000;
测试结果:
- 显示每种岗位的雇员总数,平均工资
参考代码:
select AVG(sal) 平均工资, count(ename) from emp group by job;
select job,count(*), format(avg(sal),2) from emp group by job;
测试结果:
🏠 多表查询
实际开发中往往数据来自不同的表,所以需要多表查询。本节我们用一个简单的公司管理系统,有三张表emp,dept,salgrade来演示如何进行多表查询。
案例:
- 显示雇员名、雇员工资以及所在部门的名字因为上面的数据来自EMP和DEPT表,因此要联合查询
分析:雇员名和雇员工资信息来自员工表,而所在部门名字的信息来自部门表,那我们需要两张表的数据进行组合。
多表查询本质:将多张表中数据进行穷举组合,多张表进行笛卡尔积。此时多张表变为单表,多表操作转化为对单表的操作!
多表笛卡尔积会有多种组合结果,但有的组合结果是没有意义的,所以只要emp表中的deptno = dept表中的deptno字段的记录,其他的都是没意义的。
参考代码:
select emp.ename,emp.sal,dept.dname from emp,dept where emp.deptno= dept.deptno;
//
select ename,sal,dname from emp,dept where emp.deptno= dept.deptno;
测试结果:
注:对于两张表中各自的特有字段在查询时,不需要指明所属哪张表,如果是共有字段则需要指明是哪一张表的,否则会发生冲突。
MySQL中一切皆表,组合之后的表也是表结构!也可以对该表结构的数据进行整合。
- 显示部门号为10的部门名,员工名和工资
参考代码:
select emp.ename,dept.dname,sal from emp,dept where (emp.deptno=dept.deptno and emp.deptno=10);
测试结果:
- 显示各个员工的姓名,工资,及工资级别
思路:工资级别以及工资信息在工资表里,因此我们需要多表查询。同时工资表中有工资等级所属的工资范围,我们可以根据范围来判断员工表中员工薪资所属等级。
参考代码:
select ename,sal,grade from emp,salgrade where sal between losal and hisal;
测试结果:
🏠 自连接
自连接是指在同一张表连接查询,也就是同一张表进行笛卡尔积。
可行性:
select * from salgrade,salgrade;
测试结果:
注:两张相同的表进行笛卡尔积,表名相同会造成冲突!我们需要对两张表进行重命名。
案例: 显示员工FORD的上级领导的编号和姓名(mgr是员工领导的编号--empno)
- 方法1:使用子查询
思路:先用子查询获取工FORD的上级领导的编号,再通过编号筛选出领导的相关信息。
参考代码:
select ename,empno from emp where empno=(select mgr from emp where ename='FORD');
测试结果:
- 方法2:使用多表查询
思路:两张相同表进行笛卡尔积,假设t1为单纯员工表,t2用来作为“查询上级表”,则我们可以根据t2的mgr找出t1中是xxx的上级的员工;然后再筛选出t2表中名字是FORD,最后筛选出t1表中所求上级的编号和姓名。
参考代码:
select t1.empno,t1.ename from emp as t1,emp as t2 where t1.empno=t2.mgr and t2.ename='FORD';
测试结果:
注:from执顺序先于where,因此where可以使用表的重命名!
🏠 子查询
子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询。
🎵 单行子查询
单行子查询:返回一行记录的查询。
-
显示SMITH同一部门的员工
参考代码:
select * from emp where deptno=(select deptno from emp where ename='SMITH');
测试结果:
🎵 多行子查询
多行子查询:返回多行记录的子查询。
- in关键字;查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自己的。
思路:我们可以根据子查询10号部门的工作岗位然后进一步筛选。
参考代码:
select ename,job,sal,deptno from emp where job in (select distinct job from emp where deptno=10) and deptno<>10;
测试结果:
如果还想知道上面条件对应的员工属于部门的名字呢?
此时我们可以用上面筛选出来的“表”再和部门表进行笛卡尔积,筛选出部门名字!
参考代码:
select ename,job,sal,dname from (select ename,job,sal,deptno from emp where job in (select distinct job from emp where deptno=10) and deptno<>10) as tmp,deptp,dept where tmp.deptno=dept.deptno;
测试结果:
注:一个SQL的查询结果也是一个表结构,MySQL一切皆表,不是物理上真实存在的表才能做笛卡尔积。同时子查询不仅能出现在where后,也能出现在from后!
- all关键字;显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号。
all表示的是查询结果中最大的
测试代码:
select ename,sal,deptno from emp where sal > all(select sal from emp where deptno=30);
//也可以使用聚合函数MAX
select ename,sal,deptno from emp where sal > (select MAX(sal) from emp where deptno=30);
测试结果:
- any关键字;显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门的员工)。
any表示的就是查询结果中的任意一个。
参考代码:
select ename,sal,deptno from emp where sal > any(select sal from emp where deptno=30);
测试代码:
🎵 多列子查询
单行子查询是指子查询只返回单列,单行数据;多行子查询是指返回单列多行数据,都是针对单列而言的,而多列子查询则是指查询返回多个列数据的子查询语句。
案例:查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人。
思路:我们需要根据两个列的字段(部门和岗位)进行筛选,然后根据筛选结果筛选出其他雇员的信息。
参考代码:
select * from emp where deptno=(select deptno from emp where ename='SMITH') and job=(select job from emp where ename='SMITH') and ename<>'SMITH';
//多列子查询
select * from emp where (deptno,job) = (select deptno,job from emp where ename='SMITH') and ename<>'SMITH';
测试结果:
注:使用多列子查询时,括号内的列顺序和数目要和子查询的列顺序和数目匹配!
总结:目前全部的子查询都在where子句中,充当判断条件!但其实任何时刻,查询出来的结构,本质在逻辑上也是表结构!
🎵 from子句中使用子查询
子查询语句出现在from子句中。这里要用到数据查询的技巧,把一个子查询当做一个临时表使用。
- 显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资
思路:先找出每个部门的平均工资(分组),再根据这个子表和原表进行笛卡尔积,筛选出原表工资大于子表平均工资并且部门号不冲突的
参考代码:
//
select ename, deptno, sal, format(asal,2) from emp, (select avg(sal) asal, deptno dt from emp group by deptno) tmp where emp.sal > tmp.asal and emp.detnnoptno=tmp.dt;
//
select emp.ename,emp.deptno,emp.sal,tmp.asal from (select AVG(sal) asal,deptno from emp group by deptno) as tmp,emp where (emp.sal > tmp.asal) and emp.depdeptno=tmp.deptno;
测试结果:
- 查找每个部门工资最高的人的姓名、工资、部门、最高工资
思路:先找出每个部门的最高工资(分组),再根据这个子表和原表进行笛卡尔积,找出原表中工资等于子表中筛选出的每个部门的最高工资的&&满足两表部门号相同。
参考代码:
select emp.deptno,emp.ename,emp.sal,tmp.msal from (select deptno,MAX(sal) msal from emp group by deptno) tmp,emp where tmp.msal = emp.sal and tmp.deptno=emp.deptno;
测试结果:
- 显示每个部门的信息(部门名,编号,地址)和人员数量
(1)方法1:使用子查询
参考代码:
select dept.dname,dept.loc,dept.deptno,tmp.num from dept,(select deptno,count(*) num from emp group by deptno) tmp where dept.deptno = tmp.deptno;
//1.对EMP表进行人员统计
//2.将上面的表看作临时表
测试结果:
(2)使用多表
参考代码:
select emp.deptno,count(*),dept.dname,dept.loc from emp,dept where emp.deptno=dept.deptno group by emp.deptno,dept.loc,dept.dname;
测试结果:
总结:解决多表问题的本质:首先是先想办法把多表转化为单表,所以MySQL中所有select的问题全部都可以转化为单表问题!
🎵 合并查询
在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。
1. union
该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。
案例:将工资大于2500或职位是MANAGER的人找出来
参考代码:
select ename,sal,job from emp where sal>2500 union select ename ,sal,job from emp where job='MANAGER';
测试结果:
2. union all
该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。
注:使用合并查询时列信息必须一样
🏠 表的内连接
内连接实际上就是利用where子句对两种表形成的笛卡儿积进行筛选,我们前面学习的查询都是内连接,也是在开发过程中使用的最多的连接查询。
语法:
select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件;
注:前面学习的都是内连接。
案例:显示SMITH的名字和部门名称
1. where
-- 用前面的写法
select ename, dname from EMP, DEPT where EMP.deptno=DEPT.deptno and
ename='SMITH';
2. 标准内连接
-- 用标准的内连接写法
select ename, dname from EMP inner join DEPT on EMP.deptno=DEPT.deptno and
ename='SMITH';
🏠 表的外连接
外连接分为左外连接和右外连接。
🎵 左外连接
如果联合查询,左侧的表完全显示我们就说是左外连接。
案例:
-- 建两张表
create table stu (id int, name varchar(30)); -- 学生表
insert into stu values(1,'jack'),(2,'tom'),(3,'kity'),(4,'nono');
create table exam (id int, grade int); -- 成绩表
insert into exam values(1, 56),(2,76),(11, 8);
- 查询所有学生的成绩,如果这个学生没有成绩,也要将学生的个人信息显示出来
参考代码:
-- 当左边表和右边表没有匹配时,也会显示左边表的数据
select * from stu left join exam on stu.id=exam.id;
测试结果:
此时左表中每一个id都会显示,即使在右表没找到相同的id。
🎵 右外连接
如果联合查询,右侧的表完全显示我们就说是右外连接。
语法:
select 字段 from 表名1 right join 表名2 on 连接条件;
案例:
- 对stu表和exam表联合查询,把所有的成绩都显示出来,即使这个成绩没有学生与它对应,也要显示出来。
参考代码:
select * from stu right join exam on stu.id=exam.id;
测试结果:
- 列出部门名称和这些部门的员工信息,同时列出没有员工的部门
1. 方法一:左外连接
select d.dname, e.* from dept d left join emp e on d.deptno=e.deptno;
2. 方法二:右外连接
select d.dname, e.* from emp e right join dept d on d.deptno=e.deptno;
测试结果:
完。
相关文章:

【MySQL】--- 复合查询 内外连接
Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏: MySQL 🏠 基本查询回顾 假设有以下表结构: 查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为…...

QT TLS initialization failed
qt使用QNetworkAccessManager下载文件(给出的链接可以在浏览器里面下载文件),下载失败, 提示“TLS initialization failed”通常是由于Qt在使用HTTPS进行文件下载时,未能正确初始化TLS(安全传输层协议&…...

系统学英语 — 句法 — 复合句
目录 文章目录 目录复合句型主语从句宾语从句表语从句定语从句状语从句同位语从句 复合句型 复合句型,即:从句。在英语中,除了谓语之外的所有句子成分都可以使用从句来充当。 主语从句 充当主语的句子,通常位于谓语之前&#x…...

指针的介绍2前
1.数组名的理解 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h>int main() {int arr[] { 1,2,3,4,5,6,7,8,9 };printf("&arr[0] %p\n", &arr[0]);printf("arr %p\n", arr);return 0; } 观察得到,数组名就是数组首…...

16.Word:石油化工设备技术❗【28】
目录 题目 NO1.2 NO3 NO4 题目 NO1.2 F12:另存为将“Word素材.docx”文件另存为“Word. docx”(“docx”为文件扩展名) 光标来到表格上方→插入→形状→新建画布→单击选中→格式→高度/宽度(格式→大小对话框→取消勾选✔锁定…...

Python-基础环境(01) 虚拟环境,Python 基础环境之虚拟环境,一篇文章助你完全搞懂!
Python的虚拟环境是一种工具,它能够创建一个隔离的独立Python环境。每个虚拟环境都有自己独立的Python解释器和安装的包,不会与其他虚拟环境或系统的全局Python环境发生冲突。虚拟环境特别适用于以下情况: 项目隔离:不同的项目可…...

Dest1ny漏洞库:用友 U8-CRM 系统 ajaxgetborrowdata.php 存在 SQL 注入漏洞
用友U8-CRM系统ajaxgetborrowdata.php存在SQL注入漏洞,文件多个方法存在SQL注入漏洞,未经身份验证的攻击者通过漏洞执行任意SQL语句,调用xp_cmdshell写入后门文件,执行任意代码,从而获取到服务器权限。 hunter app.n…...

java.sql.Date 弃用分析与替代方案
引言 java.sql.Date 是 Java 标准库中的一个类,它继承自 java.util.Date,主要用于在 Java 应用程序与数据库之间进行日期数据的传输。然而,随着 Java 语言的发展,java.sql.Date 以及其父类 java.util.Date 逐渐被认为存在设计缺陷…...

HarmonyOS:状态管理最佳实践
一、概述 在声明式UI编程范式中,UI是应用程序状态的函数,应用程序状态的修改会更新相应的UI界面。ArkUI采用了MVVM模式,其中ViewModel将数据与视图绑定在一起,更新数据的时候直接更新视图。如下图所示: ArkUI的MVVM模式…...

如何提高新产品研发效率
优化研发流程、采用先进工具、提升团队协作、持续学习与改进,是提高新产品研发效率的关键。其中,优化研发流程尤为重要。通过简化流程,减少不必要的环节和复杂性,企业可以显著提升研发效率。例如,采用自动化测试工具和…...

MongoDB平替数据库对比
背景 项目一直是与实时在线监测相关,特点数据量大,读写操作大,所以选用的是MongoDB。但按趋势来讲,需要有一款国产数据库可替代,实现信创要求。选型对比如下 1. IoTDB 这款是由清华大学主导的开源时序数据库&#x…...

JavaScript系列(46)-- WebGL图形编程详解
JavaScript WebGL图形编程详解 🎨 今天,让我们深入探讨JavaScript的WebGL图形编程。WebGL是一种基于OpenGL ES的JavaScript API,它允许我们在浏览器中渲染高性能的2D和3D图形。 WebGL基础概念 🌟 💡 小知识ÿ…...

YOLO目标检测4
一. 参考资料 《YOLO目标检测》 by 杨建华博士 本篇文章的主要内容来自于这本书,只是作为学习记录进行分享。 二. 环境搭建 (1) ubuntu20.04 anaconda安装方法 (2) 搭建yolo训练环境 # 首先,我们建议使用Anaconda来创建一个conda的虚拟环境 conda cre…...

十三先天记
没有一刻,只有当下在我心里。我像星星之间的空间一样空虚。他们是我看到的第一件事,我知道的第一件事。 在接下来的时间里,我意识到我是谁,我是谁。我知道星星在我上方,星球的固体金属体在我脚下。这个支持我的世界是泰…...

【论文阅读笔记】“万字”关于深度学习的图像和视频阴影检测、去除和生成的综述笔记 | 2024.9.3
论文“Unveiling Deep Shadows: A Survey on Image and Video Shadow Detection, Removal, and Generation in the Era of Deep Learning”内容包含第1节简介、第2-5节分别对阴影检测、实例阴影检测、阴影去除和阴影生成进行了全面的综述。第6节深入讨论了阴影分析࿰…...

Android AOP:aspectjx
加入引用 在整个项目的 build.gradle 中,添加 classpath "com.hujiang.aspectjx:gradle-android-plugin-aspectjx:2.0.10" 可以看到测试demo的 gradle 版本是很低的。 基于 github 上的文档,可以看到原版只支持到 gradle 4.4 。后续需要使…...

前端【11】HTML+CSS+jQUery实战项目--实现一个简单的todolist
前端【8】HTMLCSSjavascript实战项目----实现一个简单的待办事项列表 (To-Do List)-CSDN博客 学过jQUery可以极大简化js代码的编写,基于之前实现的todolist小demo,了解如何使用 jQuery 来实现常见的动态交互功能。 修改后的js代码 关键点解析 动态添加…...

2025课题推荐——USBL与DVL数据融合的实时定位系统
准确的定位技术是现代海洋探测、海洋工程和水下机器人操作的基础。超短基线(USBL)和多普勒速度计(DVL)是常用的水下定位技术,但单一技术难以应对复杂环境。因此,USBL与DVL的数据融合以构建实时定位系统&…...

滑动窗口详解:解决无重复字符的最长子串问题
滑动窗口详解:解决无重复字符的最长子串问题 在算法面试中,“无重复字符的最长子串”问题是一个经典题目,不仅考察基础数据结构的运用,还能够反映你的逻辑思维能力。而在解决这个问题时,滑动窗口(Sliding …...

第05章 11 动量剖面可视化代码一则
在计算流体力学(CFD)中,动量剖面(Momentum Profiles)通常用于描述流体在流动方向上的动量分布。在 VTK 中,可以通过读取速度场数据,并计算和展示动量剖面来可视化呈现速度场信息。 示例代码 以…...

MySQL的复制
一、概述 1.复制解决的问题是让一台服务器的数据与其他服务器保持同步,即主库的数据可以同步到多台备库上,备库也可以配置成另外一台服务器的主库。这种操作一般不会增加主库的开销,主要是启用二进制日志带来的开销。 2.两种复制方式…...

Cpp::IO流(37)
文章目录 前言一、C语言的输入与输出二、什么是流?三、C IO流C标准IO流C文件IO流以写方式打开文件以读方式打开文件 四、stringstream的简单介绍总结 前言 芜湖,要结束喽! 一、C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是 …...

基于OpenCV实现的答题卡自动判卷系统
一、图像预处理 🌄 二、查找答题卡轮廓 📏 三、透视变换 🔄 四、判卷与评分 🎯 五、主函数 六、完整代码+测试图像集 总结 🌟 在这篇博客中,我将分享如何使用Python结合OpenCV库开发一个答题卡自动判卷系统。这个系统能够自动从扫描的答题卡中提取信…...

如何将电脑桌面默认的C盘设置到D盘?详细操作步骤!
将电脑桌面默认的C盘设置到D盘的详细操作步骤! 本博文介绍如何将电脑桌面(默认为C盘)设置在D盘下。 首先,在D盘建立文件夹Desktop,完整的路径为D:\Desktop。winR,输入Regedit命令。(或者单击【…...

二十三种设计模式-享元模式
享元模式(Flyweight Pattern)是一种结构型设计模式,旨在通过共享相同对象来减少内存使用,尤其适合在大量重复对象的情况下。 核心概念 享元模式的核心思想是将对象的**可共享部分(内部状态)提取出来进行共…...

算法【有依赖的背包】
有依赖的背包是指多个物品变成一个复合物品(互斥),每件复合物品不要和怎么要多种可能性展开。时间复杂度O(物品个数 * 背包容量),额外空间复杂度O(背包容量)。 下面通过题目加深理解。 题目一 测试链接:[NOIP2006 提…...

A7. Jenkins Pipeline自动化构建过程,可灵活配置多项目、多模块服务实战
服务容器化构建的环境配置构建前需要解决什么下面我们带着问题分析构建的过程:1. 如何解决jenkins执行环境与shell脚本执行环境不一致问题?2. 构建之前动态修改项目的环境变量3. 在通过容器打包时避免不了会产生比较多的不可用的镜像资源,这些资源要是不及时删除掉时会导致服…...

飞牛NAS新增虚拟机功能,如果使用虚拟机网卡直通安装ikuai软路由(如何解决OVS网桥绑定失败以及打开ovs后无法访问飞牛nas等问题)
文章目录 📖 介绍 📖🏡 演示环境 🏡📒 飞牛NAS虚拟机安装爱快教程 📒🛠️ 前期准备🌐 网络要求💾 下载爱快镜像🚀 开始安装💻 开启IOMMU直通🌐 配置网络🚨 解决OVS网桥绑定失败以及打开ovs后无法访问飞牛nas等问题➕ 创建虚拟机🎯 安装ikuai💻 进…...

蓝桥杯例题四
每个人都有无限潜能,只要你敢于去追求,你就能超越自己,实现梦想。人生的道路上会有困难和挑战,但这些都是成长的机会。不要被过去的失败所束缚,要相信自己的能力,坚持不懈地努力奋斗。成功需要付出汗水和努…...

八股——Java基础(四)
目录 一、泛型 1. Java中的泛型是什么 ? 2. 使用泛型的好处是什么? 3. Java泛型的原理是什么 ? 什么是类型擦除 ? 4.什么是泛型中的限定通配符和非限定通配符 ? 5. List和List 之间有什么区别 ? 6. 可以把List传递给一个接受List参数的方法吗? 7. Arra…...