MySQL--复合查询--内外链接--0422

news2025/2/28 12:50:43

注:为了方便查看 mysql语句会有突然的换行,书写时请勿模仿。

目录

1.单表查询回顾

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

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

2.多表查询

比如需要查询雇员名字和所在部门编号及部门名字。

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

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

2.2 多表查询总结

3.自连接

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

 4. 子查询

4.1 单行子查询

显示SMITH同一部门的员工

4.2 多行子查询

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

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

 4.3 多列子查询

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

4.4 在from子句中使用子查询

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

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

4.5 合并查询

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


1.单表查询回顾

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

可以使用如下语句吗?

select ename,max(sal) from emp;

 max(sal)是聚合函数,把整个表当做一个数据来看,但是ename不能将整个表当做一个数据,所以会出现错误。但是如果select筛选的表结构是max(sal)显示出来的表,那么就不会再有错误了。所以用过两条语句也可以达成目的。

select max(sal) from emp;

select ename,job from emp where sal=5000; -->5000就是表里面最大值

select是支持嵌套的

select ename, job from EMP where sal = (select max(sal) from EMP);

有一条select语句的结果被当做某条select的条件,这条select语句称为子查询。执行顺序类似递归。注意子查询设置的别名,在主查询中依然看不到!

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

mysql> select ename,job from emp where sal>(select avg(sal) from emp);
+-------+-----------+
| ename | job       |
+-------+-----------+
| JONES | MANAGER   |
| BLAKE | MANAGER   |
| CLARK | MANAGER   |
| SCOTT | ANALYST   |
| KING  | PRESIDENT |
| FORD  | ANALYST   |
+-------+-----------+

2.多表查询

有时仅使用一张表达不到查询效果。

比如需要查询雇员名字和所在部门编号及部门名字。

由于雇员名字在emp表中,而部门名字在dept表中,因此需要联合查询。

mysql> select * from dept,emp;

 上述语句也会生成一个表,这个表是dept和emp的笛卡尔积。

 笛卡尔积会出现很多冗余数据是没有意义的,可以使用两张表有关联的部分进行筛选。比如部门编号。

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

 这张表就是多表查询后最完整的表,然后就可以从这张表里挑需要的数据进行显示了。

mysql> select ename,emp.deptno,dname from dept,emp where dept.deptno=emp.deptno;
+--------+--------+------------+
| ename  | deptno | dname      |
+--------+--------+------------+
| SMITH  |     20 | RESEARCH   |
| ALLEN  |     30 | SALES      |
| WARD   |     30 | SALES      |
| JONES  |     20 | RESEARCH   |
| MARTIN |     30 | SALES      |
| BLAKE  |     30 | SALES      |
| CLARK  |     10 | ACCOUNTING |
| SCOTT  |     20 | RESEARCH   |
| KING   |     10 | ACCOUNTING |
| TURNER |     30 | SALES      |
| ADAMS  |     20 | RESEARCH   |
| JAMES  |     30 | SALES      |
| FORD   |     20 | RESEARCH   |
| MILLER |     10 | ACCOUNTING |
+--------+--------+------------+

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

mysql> select dname,ename,sal from emp,dept where emp.deptno=dept.deptno 
                and dept.deptno=10;
+------------+--------+---------+
| dname      | ename  | sal     |
+------------+--------+---------+
| ACCOUNTING | CLARK  | 2450.00 |
| ACCOUNTING | KING   | 5000.00 |
| ACCOUNTING | MILLER | 1300.00 |
+------------+--------+---------+

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

mysql> select ename,sal,grade from emp,salgrade where emp.sal between losal and hisal;
+--------+---------+-------+
| ename  | sal     | grade |
+--------+---------+-------+
| SMITH  |  800.00 |     1 |
| ALLEN  | 1600.00 |     3 |
| WARD   | 1250.00 |     2 |
| JONES  | 2975.00 |     4 |
| MARTIN | 1250.00 |     2 |
| BLAKE  | 2850.00 |     4 |
| CLARK  | 2450.00 |     4 |
| SCOTT  | 3000.00 |     4 |
| KING   | 5000.00 |     5 |
| TURNER | 1500.00 |     3 |
| ADAMS  | 1100.00 |     1 |
| JAMES  |  950.00 |     1 |
| FORD   | 3000.00 |     4 |
| MILLER | 1300.00 |     2 |
+--------+---------+-------+
14 rows in set (0.00 sec)

2.2 多表查询总结

多表组合,形成笛卡尔积本质上就是数据的穷举。

解决多表查询的思路:

  1. 先确定和哪些表有关系
  2. 让几张有联系的表形成笛卡尔积
  3. 在形成的笛卡尔积中添加筛选条件,将多表查询看做为一张表的查询

3.自连接

自连接是指在同一张表连接查询。
 

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

可以发现当前语句在书写时,需要在emp表中查找名字为ford的数据而且在显示筛选条件时也是在emp表中。称为子连接。

可以使用子查询来写

mysql> select empno,ename from emp where 
                empno=(select mgr from emp where ename='FORD');
+--------+-------+
| empno  | ename |
+--------+-------+
| 007566 | JONES |
+--------+-------+

也可以使用多表查询

 同一张表不能直接查询两次,但是如果将该表起别名,就可以拼起来了。

mysql> select leader.empno,leader.ename from emp leader,emp worker 
            where worker.mgr=leader.empno and worker.ename='ford';
+--------+-------+
| empno  | ename |
+--------+-------+
| 007566 | JONES |
+--------+-------+

 4. 子查询

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

4.1 单行子查询

显示SMITH同一部门的员工

mysql> select ename,deptno from emp where deptno=(select deptno from emp where ename='smith');
+-------+--------+
| ename | deptno |
+-------+--------+
| SMITH |     20 |
| JONES |     20 |
| SCOTT |     20 |
| ADAMS |     20 |
| FORD  |     20 |
+-------+--------+

4.2 多行子查询

in

in (...)

在(...)范围中

all

all(...)

比(...)范围内都

any

any(...)

比(...)范围内任意一个

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

mysql> select * from emp where job in
        (select distinct job from emp where deptno=10) and deptno!=10;
+--------+-------+---------+------+---------------------+---------+------+--------+
| empno  | ename | job     | mgr  | hiredate            | sal     | comm | deptno |
+--------+-------+---------+------+---------------------+---------+------+--------+
| 007566 | JONES | MANAGER | 7839 | 1981-04-02 00:00:00 | 2975.00 | NULL |     20 |
| 007698 | BLAKE | MANAGER | 7839 | 1981-05-01 00:00:00 | 2850.00 | NULL |     30 |
| 007369 | SMITH | CLERK   | 7902 | 1980-12-17 00:00:00 |  800.00 | NULL |     20 |
| 007876 | ADAMS | CLERK   | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL |     20 |
| 007900 | JAMES | CLERK   | 7698 | 1981-12-03 00:00:00 |  950.00 | NULL |     30 |
+--------+-------+---------+------+---------------------+---------+------+--------+

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

mysql> select ename,sal,deptno from emp where 
            sal>all(select sal from emp where deptno=30);
+-------+---------+--------+
| ename | sal     | deptno |
+-------+---------+--------+
| JONES | 2975.00 |     20 |
| SCOTT | 3000.00 |     20 |
| KING  | 5000.00 |     10 |
| FORD  | 3000.00 |     20 |
+-------+---------+--------+

 4.3 多列子查询

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

mysql> select * from emp where (deptno,job)=
            (select deptno,job from emp where ename='smith');
+--------+-------+-------+------+---------------------+---------+------+--------+
| empno  | ename | job   | mgr  | hiredate            | sal     | comm | deptno |
+--------+-------+-------+------+---------------------+---------+------+--------+
| 007369 | SMITH | CLERK | 7902 | 1980-12-17 00:00:00 |  800.00 | NULL |     20 |
| 007876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL |     20 |
+--------+-------+-------+------+---------------------+---------+------+--------+


mysql> select * from emp where (deptno,job)=
            (select deptno,job from emp where ename='smith') and ename!='smith';
+--------+-------+-------+------+---------------------+---------+------+--------+
| empno  | ename | job   | mgr  | hiredate            | sal     | comm | deptno |
+--------+-------+-------+------+---------------------+---------+------+--------+
| 007876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL |     20 |
+--------+-------+-------+------+---------------------+---------+------+--------+

4.4 在from子句中使用子查询

本质上还是多表查询,无非是把select的结果当做一个临时的表和其他表拼起来。

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

(1)先求一下每个部门的平均工资

mysql> select avg(sal), deptno from emp group by deptno;
+-------------+--------+
| avg(sal)    | deptno |
+-------------+--------+
| 2916.666667 |     10 |
| 2175.000000 |     20 |
| 1566.666667 |     30 |

(2)把平均工资表和emp表拼起来,形成笛卡尔积,然后进行条件筛选。

mysql> select * from emp,
        (select avg(sal) avgsal, deptno dt from emp group by deptno) tmp 
            where emp.deptno=tmp.dt;
+--------+--------+-----------+------+---------------------+---------+---------+--------+-------------+------+
| empno  | ename  | job       | mgr  | hiredate            | sal     | comm    | deptno | avgsal      | dt   |
+--------+--------+-----------+------+---------------------+---------+---------+--------+-------------+------+
| 007369 | SMITH  | CLERK     | 7902 | 1980-12-17 00:00:00 |  800.00 |    NULL |     20 | 2175.000000 |   20 |
| 007499 | ALLEN  | SALESMAN  | 7698 | 1981-02-20 00:00:00 | 1600.00 |  300.00 |     30 | 1566.666667 |   30 |
| 007521 | WARD   | SALESMAN  | 7698 | 1981-02-22 00:00:00 | 1250.00 |  500.00 |     30 | 1566.666667 |   30 |
| 007566 | JONES  | MANAGER   | 7839 | 1981-04-02 00:00:00 | 2975.00 |    NULL |     20 | 2175.000000 |   20 |
| 007654 | MARTIN | SALESMAN  | 7698 | 1981-09-28 00:00:00 | 1250.00 | 1400.00 |     30 | 1566.666667 |   30 |
| 007698 | BLAKE  | MANAGER   | 7839 | 1981-05-01 00:00:00 | 2850.00 |    NULL |     30 | 1566.666667 |   30 |
| 007782 | CLARK  | MANAGER   | 7839 | 1981-06-09 00:00:00 | 2450.00 |    NULL |     10 | 2916.666667 |   10 |
| 007788 | SCOTT  | ANALYST   | 7566 | 1987-04-19 00:00:00 | 3000.00 |    NULL |     20 | 2175.000000 |   20 |
| 007839 | KING   | PRESIDENT | NULL | 1981-11-17 00:00:00 | 5000.00 |    NULL |     10 | 2916.666667 |   10 |
| 007844 | TURNER | SALESMAN  | 7698 | 1981-09-08 00:00:00 | 1500.00 |    0.00 |     30 | 1566.666667 |   30 |
| 007876 | ADAMS  | CLERK     | 7788 | 1987-05-23 00:00:00 | 1100.00 |    NULL |     20 | 2175.000000 |   20 |
| 007900 | JAMES  | CLERK     | 7698 | 1981-12-03 00:00:00 |  950.00 |    NULL |     30 | 1566.666667 |   30 |
| 007902 | FORD   | ANALYST   | 7566 | 1981-12-03 00:00:00 | 3000.00 |    NULL |     20 | 2175.000000 |   20 |
| 007934 | MILLER | CLERK     | 7782 | 1982-01-23 00:00:00 | 1300.00 |    NULL |     10 | 2916.666667 |   10 |
+--------+--------+-----------+------+---------------------+---------+---------+--------+-------------+------+

(3)进行筛选

mysql> select ename,deptno,sal,avgsal from emp,
        (select avg(sal) avgsal, deptno dt from emp group by deptno)tmp 
            where emp.deptno=tmp.dt and emp.sal>tmp.avgsal;

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

(1)先筛出来最高工资

mysql> select max(sal) maxsal,deptno from emp group by deptno;
+---------+--------+
| maxsal  | deptno |
+---------+--------+
| 5000.00 |     10 |
| 3000.00 |     20 |
| 2850.00 |     30 |
+---------+--------+

 (2) 将最高工资表和emp表拼起来

mysql> select* from emp,(select max(sal) maxsal,deptno 
            from emp group by deptno) tmp 
                where emp.deptno=tmp.deptno;

(3)加上限制条件和需要显示的信息列

mysql> select ename,emp.deptno,sal,maxsal from emp,
            (select max(sal) maxsal,deptno from emp group by deptno) tmp 
                    where emp.deptno=tmp.deptno and emp.sal=maxsal;
+-------+--------+---------+---------+
| ename | deptno | sal     | maxsal  |
+-------+--------+---------+---------+
| BLAKE |     30 | 2850.00 | 2850.00 |
| SCOTT |     20 | 3000.00 | 3000.00 |
| KING  |     10 | 5000.00 | 5000.00 |
| FORD  |     20 | 3000.00 | 3000.00 |
+-------+--------+---------+---------+

4.5 合并查询

为了合并多个select的执行结果,可以使用集合操作符 union(自带去重),union all(不去重)

union的两个表的结构必须相同,否则union出来的结果无意义。

mysql> select ename,sal from emp where sal>2500 
        union select sal,job from emp where job='manager';
+---------+---------+
| ename   | sal     |
+---------+---------+
| JONES   | 2975.00 |
| BLAKE   | 2850.00 |
| SCOTT   | 3000.00 |
| KING    | 5000.00 |
| FORD    | 3000.00 |
| 2975.00 | MANAGER |
| 2850.00 | MANAGER |
| 2450.00 | MANAGER |
+---------+---------+

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

mysql> select ename,sal,job from emp where sal>2500 
        union select ename,sal,job from emp where job='manager';
+-------+---------+-----------+
| ename | sal     | job       |
+-------+---------+-----------+
| JONES | 2975.00 | MANAGER   |
| BLAKE | 2850.00 | MANAGER   |
| SCOTT | 3000.00 | ANALYST   |
| KING  | 5000.00 | PRESIDENT |
| FORD  | 3000.00 | ANALYST   |
| CLARK | 2450.00 | MANAGER   |
+-------+---------+-----------+

5.内外连接

5.1内连接

select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件;

select ename, dname from EMP, DEPT where EMP.deptno=DEPT.deptno and
ename='SMITH';

select ename, dname from EMP inner join DEPT on EMP.deptno=DEPT.deptno and
ename='SMITH';

上述使用的全都是内连接

inner join 相当于求两个表的交集。

 5.2外连接

外连接分为左外连接和右外连接。如果联合查询,左侧的表完全显示,称为左外连接

右侧的表完全显示,称为右外连接。

select 字段名 from 表名1 left join 表名2 on 连接条件

内连接和外连接的区别在于

  • left/right join相当于求left/right表的全集。没有对应的列属性就置成NULL
  • 内连接是求交集

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

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

相关文章

win10+使用cmake编译最新的ceres-solver库

参考文献 点击这里访问 感谢大佬! 说明 我这个只编译了release版本,如果还需要debug版本,cmake编译和vs编译都需要另外设置一些东西,我没有弄。 文章目录 参考文献说明1. 需要使用的库2. 需要的工具3. 准备工作3.1 建一个文件…

Neovim-配置教程

环境:Ubuntu 20.04 宿主机:windows (windows terminal)WSL2 NVIM:v0.10.0-dev 配置Neovim 需要保证流畅的github环境(以便于快速拉取插件),可以使用代理或是配置Github SSH key 本文…

【OpenCV-Python】——Haar人脸检测深度学习人脸检测EigenFaces/FisherFaces/LBPH人脸识别

目录 前言: 1、人脸检测 1.1 基于Haar的人脸检测 1.2 基于深度学习的人脸检测 2、人脸识别 2.1 EigenFaces人脸识别 2.2 FisherFaces人脸识别 2.3 LBPH人脸识别 总结: 前言: 人脸检测是人脸定位的过程;人脸识别是在人脸…

macOS 下载汇总(系统、应用和教程) 2023 持续更新中

macOS Ventura 13, macOS Monterey 12, macOS Big Sur 11, macOS Catalina 10.15, macOS Mojave 10.14, macOS High Sierra 10.13, macOS Sierra 10.12 请访问原文链接:https://sysin.org/blog/macOS/,查看最新版。原创作品,转载请保留出处。…

VMware Aria Suite 8.12 - 云管理解决方案 (下载索引)

VMware Aria Suite 8.12 - 云管理解决方案 (下载索引) 请访问原文链接:https://sysin.org/blog/vmware-aria-suite/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org 云管理套包 VMware Aria Suite(以前…

网络基础知识(2)——简单说说IP地址

Internet 依靠 TCP/IP 协议,在全球范围内实现不同硬件结构、不同操作系统、不同网络系统的主机之间的互联。在 Internet 上,每一个节点都依靠唯一的 IP 地址相互区分和相互联系,IP 地址用于标识互联网中的每台主机的身份,设计人员…

Windows 20个经典cmd命令,值得收藏

本文重点介绍Windows系统常用工具和服务的快捷启动命令。相比鼠标多次点击打开窗口,输入命令回车一键打开更为快捷高效。喜欢请点赞收藏,关注我获取最新原创分享~ 一、Windows启动命令使用方式 快捷键 【徽标R】打开命令窗口 输入命令,点击【…

ARM 栈帧(一)

ARM 栈帧 本系列均以 corter-A7(armv7-a) 为例 在 ARM 中,通常为满减栈(Full Descending FD), 也就是说,堆栈指针指向堆栈内存中最后一个填充的位置,并且随着每个新数据项被压入堆栈而递减。 栈的本质 要理解栈的本…

基于NXP+FPGA的大容量固态存储板实现方案

1 概述 近年来 ,大容量数据存储设备受到软硬件等发展的限制主 要还是采用机械硬盘叠加组合而用。机械硬盘以磁盘片作为载 体 ,采用机械马达 ,存在抗振性能低、低温性能差、噪声大等缺点。 固态硬盘是以半导体作为存储介质及控制载体 &…

使用马哈鱼SQLFLow 1 分钟获取复杂 SQL 语句的血缘关系

数据血缘关系在企业的数据治理中是非常重要的一个环节,关于数据血缘在企业数据治理中的重要作用,可以参考这篇文章。SQL 语言在数据处理中被广泛使用,SQL 语句中包含了丰富的数据血缘关系,关于什么是 SQL 中的数据血缘&#xff0c…

死锁与活锁

1 死锁概述 死锁主要是由于资源使用不当引发的。OS中存在很多不同类型的软硬件资源,而可以引发死锁的资源 主要是需要互斥访问的、不可被抢占的资源,即临界资源。下面先来简单了解下资源的分类。 资源分类 按照资源是否可重复使用划分,可以分…

Spring ( 三 ) SpringIoC

3.SpringIoC Spring 核心 是 通过IoC 降低 项目中的类之间的耦合 IoC Inversion of Control 控制反转: 应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。 ​ 这样控制权就由应用转移到了外部容器,控制权的转移…

【Linux从入门到精通】一文带你理解进程概念

我们通过对上篇文章冯诺依曼体系结构对硬件进行讲解后, 本篇文章会对进程进行深入讲解。同时会讲解PCB(进程控制块)。希望本篇文章内容会对你有所帮助。 文章目录 一、再次理解操作系统 1、1 操作系统的作用 1、2 操作系统的管理 二、进程基本…

基于Kubernetes集群构建大中型企业CICD应用平台(5)--Integrate工具

5.1、jenkins介绍 持续集成、持续部署的工具很多,其中Jenkins是一个开源的持续集成平台。 Jenkins涉及到将编写完毕的代码发布到测试环境和生产环境的任务,并且还涉及到了构建项目等任务。 Jenkins需要大量的插件保证工作,安装成本较高&am…

Java Web开发:Spring Boot和Spring Cloud的应用和实践

一、介绍 Java Web开发是当今互联网时代中的一项重要技术,随着互联网的发展和应用场景的不断扩大,Java Web开发技术也得到了广泛的应用。而Spring Boot和Spring Cloud作为Java Web开发中最常用的技术之一,已经成为了很多开发者必备的技能。本…

使用Vue3和Typescript实现可复用的路由标签页和面包屑导航组件

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: 三十天精通 Vue 3 文章目录 一、为什么需要可复用的路由标签页和面包屑导航组件1.1 前端应用导航的问题1.2 解决问题的方法二、Vue3和Typescript基础知识回…

shell脚本中数组的运用以及排序算法

shell脚本中数组的运用 一、数组的介绍1、概念2、定义方法3、数组包括的数据类型 二、关于数组的操作1、获取数组长度2、获取数组各个元素的下标3、获取数组列表或单个元素4、对数组切片输出5、对数组里的元素替换6、删除单个元素或数组7、数组追加元素8、向函数传入数组的值 三…

Learning C++ No.20 【红黑树实战】

引言: 北京时间:2023/5/12/20:30,今天周五,周五不摆烂从我做起,虽然刚睡醒,但是今天如果论学习时长,那可能是许久以来最长的一天,从早上6:40晨跑回来坐在凳子上,一坐久坐…

在 I/O 看未来 | 开发者集合!官方学习资源已更新,即 课 解锁新技能!

看完 Google I/O 2023 的精彩内容 你是否已跃跃欲试,准备充电学习? 马上跟随 Google 开发者在线课程 刷新知识储备和开发技能 将技术热爱落地为实践应用! "解码 Google I/O 洞见科技未来" 征文活动 也向身为技术爱好者的你发出召唤…

【Wi-Fi】802.11/802.11b/802.11g/802.11n/802.11a/802.11ac/802.11ax/802.11be

WiFi发展历史 IEEE 802.11 Protocol Release Date Frequency Band Bandwidth Max Throughput 802.11-1997 1997 2.4GHz 22MHz 2Mbps 802.11b 1999 2.4GHz 22MHz 11Mbps 802.11a 1999 5GHz 20MHz 54Mbps 802.11g 2003 2.4GHz 20MHz 54Mbps 802.11n (W…