复合查询【MySQL】

文章目录

  • 复合查询
    • 测试表
  • 单表查询
  • 多表查询
  • 子查询
    • 单行子查询
    • 多行子查询
      • IN 关键字
      • ALL 关键字
      • ANY 关键字
    • 多列子查询
  • 合并查询

复合查询

测试表

雇员信息表中包含三张表,分别是员工表(emp)、部门表(dept)和工资等级表(salgrade)。

员工表(emp):

  • 雇员编号(empno)
  • 雇员姓名(ename)
  • 雇员职位(job)
  • 雇员领导编号(mgr)
  • 雇佣时间(hiredate)
  • 工资月薪(sal)
  • 奖金(comm)
  • 部门编号(deptno)

部门表(dept):

  • 部门编号(deptno)
  • 部门名称(dname)
  • 部门所在地点(loc)

工资等级表(salgrade):

  • 等级(grade)
  • 此等级最低工资(losal)
  • 此等级最高工资(hisal)

雇员信息表的 SQL:

DROP database IF EXISTS `scott`;
CREATE database IF NOT EXISTS `scott` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;USE `scott`;DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept` (`deptno` int(2) unsigned zerofill NOT NULL COMMENT '部门编号',`dname` varchar(14) DEFAULT NULL COMMENT '部门名称',`loc` varchar(13) DEFAULT NULL COMMENT '部门所在地点'
);DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp` (`empno` int(6) unsigned zerofill NOT NULL COMMENT '雇员编号',`ename` varchar(10) DEFAULT NULL COMMENT '雇员姓名',`job` varchar(9) DEFAULT NULL COMMENT '雇员职位',`mgr` int(4) unsigned zerofill DEFAULT NULL COMMENT '雇员领导编号',`hiredate` datetime DEFAULT NULL COMMENT '雇佣时间',`sal` decimal(7,2) DEFAULT NULL COMMENT '工资月薪',`comm` decimal(7,2) DEFAULT NULL COMMENT '奖金',`deptno` int(2) unsigned zerofill DEFAULT NULL COMMENT '部门编号'
);DROP TABLE IF EXISTS `salgrade`;
CREATE TABLE `salgrade` (`grade` int(11) DEFAULT NULL COMMENT '等级',`losal` int(11) DEFAULT NULL COMMENT '此等级最低工资',`hisal` int(11) DEFAULT NULL COMMENT '此等级最高工资'
);insert into dept (deptno, dname, loc)
values (10, 'ACCOUNTING', 'NEW YORK');
insert into dept (deptno, dname, loc)
values (20, 'RESEARCH', 'DALLAS');
insert into dept (deptno, dname, loc)
values (30, 'SALES', 'CHICAGO');
insert into dept (deptno, dname, loc)
values (40, 'OPERATIONS', 'BOSTON');insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20', 1600, 300, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7521, 'WARD', 'SALESMAN', 7698, '1981-02-22', 1250, 500, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7566, 'JONES', 'MANAGER', 7839, '1981-04-02', 2975, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28', 1250, 1400, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01', 2850, null, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09', 2450, null, 10);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19', 3000, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7839, 'KING', 'PRESIDENT', null, '1981-11-17', 5000, null, 10);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7844, 'TURNER', 'SALESMAN', 7698,'1981-09-08', 1500, 0, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23', 1100, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7900, 'JAMES', 'CLERK', 7698, '1981-12-03', 950, null, 30);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7902, 'FORD', 'ANALYST', 7566, '1981-12-03', 3000, null, 20);insert into emp (empno, ename, job, mgr, hiredate, sal, comm, deptno)
values (7934, 'MILLER', 'CLERK', 7782, '1982-01-23', 1300, null, 10);insert into salgrade (grade, losal, hisal) values (1, 700, 1200);
insert into salgrade (grade, losal, hisal) values (2, 1201, 1400);
insert into salgrade (grade, losal, hisal) values (3, 1401, 2000);
insert into salgrade (grade, losal, hisal) values (4, 2001, 3000);
insert into salgrade (grade, losal, hisal) values (5, 3001, 9999);

这些 SQL 将保存在一个以.sql结尾的文件中,然后再 MySQL 中使用 source 命令执行它:

image-20231120224457885 image-20231120224535610

部门表的结构和内容:

image-20231120224615277

员工表的结构和内容:

image-20231120224654193

工资等级表的结构和内容:

image-20231120224735460

单表查询

  • 查询工资高于 500 或岗位为 MANAGER 的员工,同时要求员工姓名的首字母为大写的 J
  1. 首先明确查询的目标是员工。
  2. 其次明确条件有 3 个,通过题意使用 AND 或 OR 连接。
  3. 这些属性都能在表emp中找到。
image-20240223141215636
  • 查询员工信息,按部门号升序而员工工资降序显示
image-20240223142015140
  • 查询员工信息,按年薪降序显示

注意年薪应该是 12 倍的月薪+奖金,而奖金可能为 NULL,为了避免年薪为 NULL,此时应该为 0

image-20240223142443930
  • 查询工资最高的员工的姓名和岗位
image-20240223142647854
  • 查询工资高于平均工资的员工信息
image-20240223142738492
  • 查询每个部门的平均工资和最高工资

group by 子句按照部门号来计算每一组的平均工资和最高工资。

image-20240223142929951
  • 查询平均工资低于 2000 的部门号和它的平均工资
image-20240223143202622

HAVING 子句通常与 GROUP BY 子句一起使用。当它在 GROUP BY 子句中使用时,我们可以应用它在 GROUP BY 子句之后来指定过滤的条件。如果省略了 GROUP BY 子句,HAVING 子句行为就像 WHERE 子句一样。

请注意,HAVING 子句应用筛选条件每一个分组的行,而 WHERE 子句的过滤条件是过滤每个单独的行。

  • 查询每种岗位的雇员总数和平均工资
image-20240223143938698

多表查询

由于在查询时可能会用到不止一张表中的属性,所以要用到多表查询,其 SQL 的语法和单表查询是类似的。

需要注意的是,多表查询实际上是从若干表的笛卡尔积中操作的。多表的笛卡尔积指的是用其中一张表的一条记录去和剩余的整张表组合,以此类推。因此笛卡尔积保存了这些表记录的所有可能的集合,但是集合中的组合并不全是有意义的,而且不同表中也可能有相同的列属性(例如雇员表和工资表都有部门号),所以在合并多表时,需要要筛选符合逻辑的组合,并且合并相同的列属性。

例如这个查询返回了一个原始的笛卡尔积集合。

image-20240223145352545

通过这个结果可以知道 MySQL 是不断地用前一张表的一条记录来和另外一个表组合来求笛卡尔积的:前半部分是雇员表,后半部分是部门表。在这一行中有两个部门号,部门号不同的记录都是没有意义的。

在用 SQL 操作不同表的相同列属性时,可以用表名。列名来表示。

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

后面的 where 子句就是在上面这个原始的笛卡尔积中筛选符合题意的记录。

image-20240223145946421
  • 显示各个员工的姓名、工资和工资级别
image-20240223150447843

员工的工资决定了工资等级,因此只有这两个属性对应才能是有意义的记录。

子查询

单行子查询

返回单行单列数据的子查询。

  • 显示 SMITH 同一部门的员工
  1. 子查询:首先查询 SMITH 的部门号 x 作为查询的依据
  2. 然后选出部门号为 x 且不是 SMITH 的员工
image-20240223151555326

多行子查询

返回多行单列数据的子查询。

IN 关键字

  • 显示和 10 号部门的工作岗位相同的员工的名字、岗位、工资和部门号,但是不包含 10 号部门的员工
  1. 子查询:首先查询 10 号部门有哪些工作岗位,查询时去重,将结果作为查询的依据
  2. 通过在查询的 where 子句中使用 IN 关键字,判断工作岗位是否在子查询的返回值中
image-20240223152440417

ALL 关键字

  • 显示工资比 30 号部门的所有员工的工资高的员工的姓名、工资和部门号
  1. 子查询:首先查询 30 号部门有哪些工资,查询时去重,将结果作为查询的依据
  2. 通过在查询的 where 子句使用 ALL 关键字,判断工资是否大于子查询的返回值。
image-20240223152816856

这是一个常见的逻辑问题,要判断某个值是否大于集合中的所有元素,只需要判断这个值是否大于集合中的最大值。这和上面是等价的。

ANY 关键字

  • 显示工资比 30 号部门的任意员工的工资高的员工的姓名、工资和部门号,包含 30 号部门的员工
  1. 子查询:首先查询 30 号部门有哪些工资,查询时去重,将结果作为查询的依据
  2. 通过在查询的 where 子句使用 ANY 关键字,判断工资是否大于子查询的返回值。
image-20240223153302976

同样地,这也可以等价地转换为求最小值的问题。

多列子查询

返回多列数据的子查询。

  • 显示和 SMITH 的部门和岗位完全相同的员工,不包含 SMITH 本人
  1. 子查询:首先查询 SMITH 的部门号和岗位,将结果作为查询的依据
  2. 在子查询的返回值中筛选名字不是 SMITH 的记录
image-20240223154037220

注意:

  • 多列子查询得到的结果是多列数据,在比较多列数据时需要将待比较的多个列用圆括号括起来,并且列属性的位置要对应。
  • 多列子查询返回的如果是多行数据,在筛选数据时也可以使用 IN、ALL 和 ANY 关键字。

子查询相当于一个新表,如上演示,它不仅可以被用在 where 子句中(筛选条件),还可以被用在 from 子句中(临时表)。

  • 显示每个高于自己部门平均工资的员工的姓名、部门、工资和部门的平均工资
  1. 计算每个部门的平均工资,作为一张表
  2. 将平均工资表和雇员表做笛卡尔积,选出部门号和平均工资表相同的记录,并且要求工资大于平均工资。
image-20240223155933165

其中子查询的别名是 avg_sal。

  • 显示每个部门工资最高的员工的姓名、工资、部门和部门的最高工资
  1. 查询每个部门的最高工资作为子查询
  2. 将最高工资表和雇员表做笛卡尔积,要求两表中的部门号相同,且员工工资在最高工资中可被查询到。
image-20240223160621799
  • 显示每个部门的部门名、部门编号、所在地址和人员数量
  1. 查询每个部门的人员数量作为子查询
  2. 将人员数量表和雇员表做笛卡尔积,要求两表的部门编号一致
image-20240223162639732

合并查询

将多个查询结果进行合并,可使用的操作符有:

  • UNION:取得两个查询结果的并集,union 会自动去掉结果集中的重复行。

  • UNION ALL:取得两个查询结果的并集,但 union all 不会去掉结果集中的重复行。

  • 显示工资大于 2500 或职位是 MANAGER 的员工

如果用 or 连接两个筛选条件:

image-20240223163700457

如果分别对两个条件做两次查询,并且用 UNION 对两个查询结果做合并:
image-20240223163839625

如果分别对两个条件做两次查询,并且用 UNION ALL 对两个查询结果做合并:

image-20240223164010642

由此可见,UNION ALL 只是单纯地对两张表进行合并,并不会做去重工作。

需要注意的是:

  • 待合并的两个查询结果的列的数量必须一致,否则无法合并。
  • 待合并的两个查询结果对应的列属性可以不一样,但不建议这样做。

这两个操作符存在的意义是,有时需要查询的属性可能来自不同的表,但是不同的表之间没有很强的关联性,所以需要硬凑,不过硬凑也需要符合逻辑。如果这些表没有共同的列属性的话,那么合并就没有意义了。

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

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

相关文章

OS-Copilot:实现具有自我完善能力的通用计算机智能体

🍉 CSDN 叶庭云:https://yetingyun.blog.csdn.net/ AI 缩小了人类间的知识和技术差距 论文标题:OS-Copilot: Towards Generalist Computer Agents with Self-Improvement 论文链接:https://arxiv.org/abs/2402.07456 项目主页&a…

【工具相关】zentao用例管理平台部署实践

文章目录 一、备份还原1、数据备份1.1、前言1.2、版本备份1.3、数据备份 2、数据恢复2.1、版本恢复2.2、数据恢复 二、问题处理1、ERROR: SQLSTATE[HY000] [2002] Connection refused 一、备份还原 1、数据备份 1.1、前言 禅道系统从10.6版本以后,新增数据备份设…

Go语言必知必会100问题-20 切片操作实战

前言 有很多gopher将切片的length和capacity混淆,没有彻底理清这两者的区别和联系。理清楚切片的长度和容量这两者的关系,有助于我们合理的对切片进行初始化、通过append追加元素以及进行复制等操作。如果没有深入理解它们,缺少高效操作切片…

云服务器python版本冲突解决(awd平台搭建)

文章目录 yum和apt-getdockerpython环境问题 大家在使用python时,难免会使用他人的代码,自己是python3,而别人的是python2.我们直接运行会报错(比如print函数括号的问题)。但是去修改代码又很麻烦。这里给大家推荐conda。我以我搭建awd平台为…

【Java.mysql】——增删查改(CRUD)之 增查(CR) 附加数据库基础知识

目录 🚩数据库操作 🎈创建数据库 🎈使用数据库 🎈删除数据库 🚩数据类型 🚩表的操作 🎈创建表 🌈查看表结构 🎈删除表 ❗练习(综合运用) 🖥️新增…

微信小程序提示确认框

如图所示,如何弹出微信小程序自带默认弹框? 代码如下: wx.showModal({ title: 确认, content: 确定要删除吗?, success (res) { if (res.confirm) { console.log(用户点击确定) } else if (res.cancel) { console.log(用…

STM32CubeIDE基础学习-STM32CubeIDE软件程序仿真调试

STM32CubeIDE基础学习-STM32CubeIDE软件程序仿真调试 前言 一般编写完程序后都会进行编译,看结果是否有存在语法错误,确认没有语法错误之后再进行代码的下载观察硬件执行是否和软件编程预期的结果一致,如果发现硬件执行达不到预期现象&#…

JWT令牌技术

写在前面 我以为,最美的日子,当是晨起侍花,闲来煮茶,阳光下打盹,细雨中漫步,夜灯下读书,在这清浅时光里,一半烟火,一半诗意,任窗外花开花落,云来云…

no main manifest attribute,in xxx.jar(关于Spring项目,无法在云服务器上运行jar包的解决方法)

目录 问题详情 解决方法 问题详情 项目可以打包正常&#xff0c;但是云服务器上无法运行&#xff0c;报错&#xff1a;no main manifest attribute&#xff0c;in xxx.jar 解决方法 1.查看pom.xml配置文件&#xff0c;检查以下代码&#xff0c;没有则加上&#xff1a; <…

B+树 和 跳表 的结构及区别,不同的用途【mysql的索引为什么使用B+树而不使用跳表?】

导语&#xff1a; 详解B树与跳表的结构及区别&#xff0c;描述B树与跳表新增数据的过程&#xff0c;解释MySQL与Redis选择对应结构的原因。 mysql数据表里直接遍历这一行行数据&#xff0c;性能就是O(n)&#xff0c;比较慢。为了加速查询&#xff0c;使用了B树来做索引&#x…

HTML5 Web Worker之性能优化

描述 由于 JavaScript 是单线程的&#xff0c;当执行比较耗时的任务时&#xff0c;就会阻塞主线程并导致页面无法响应&#xff0c;这就是 Web Workers 发挥作用的地方。它允许在一个单独的线程&#xff08;称为工作线程&#xff09;中执行耗时的任务。这使得 JavaScript 代码可…

第三周组会——动态多目标优化算法

首先对上周写的DF测试函数进行了优化和增加 DF4 pf: DF5测试函数PF DF6 遇到的问题,在算法问题的参数taut(变化频率)默认是10数字变小时就算是9,算法会跟不上收敛 新读的文献 A Novel Dynamic Multiobjective Optimization Algorithm With Hierarchical Response System 一…

1.2_3 TCP/IP参考模型

文章目录 1.2_3 TCP/IP参考模型&#xff08;一&#xff09;OSI参考模型与TCP/IP参考模型&#xff08;二&#xff09;5层参考模型&#xff08;三&#xff09;5层参考模型的数据封装与解封装 1.2_3 TCP/IP参考模型 &#xff08;一&#xff09;OSI参考模型与TCP/IP参考模型 TCP/I…

【理解指针(1)】

理解指针&#xff08;1&#xff09; 1什么是内存2指针变量和地址21 取地址操作符&#xff08;&&#xff09;22 指针变量23 解引用操作符&#xff08;*&#xff09;24 指针变量的大小 3指针变量的意义31指针的解引用32 指针加减整数33 void* 指针 4. const 修饰指针41 const…

递归搜索回溯相关的题目解析和练习2

前言 大家好&#xff0c;我是jiantaoyab&#xff0c;下面的题目用的方法和前面几篇的方法是一样的&#xff0c;写起来是比较困难的&#xff0c;加油 字母大小写全排列 https://leetcode.cn/problems/letter-case-permutation/ 解析 代码 class Solution {vector<string&g…

【Docker】容器的概念

容器技术&#xff1a;容器技术是基于虚拟化技术的&#xff0c;它使应用程序从一个计算机环境快速可靠地转移到另一个计算机环境中&#xff0c;可以说是一个新型地虚拟化技术。 一、docker容器 Docker:是一个开源地容器引擎Docker 是一种轻量级的容器化技术&#xff0c;其主要原…

分割模型TransNetR的pytorch代码学习笔记

这个模型在U-net的基础上融合了Transformer模块和残差网络的原理。 论文地址&#xff1a;https://arxiv.org/pdf/2303.07428.pdf 具体的网络结构如下&#xff1a; 网络的原理还是比较简单的&#xff0c; 编码分支用的是预训练的resnet模块&#xff0c;解码分支则重新设计了。…

PyTorch搭建LeNet训练集详细实现

一、下载训练集 导包 import torch import torchvision import torch.nn as nn from model import LeNet import torch.optim as optim import torchvision.transforms as transforms import matplotlib.pyplot as plt import numpy as npToTensor()函数&#xff1a; 把图像…

git学习(创建项目提交代码)

操作步骤如下 git init //初始化git remote add origin https://gitee.com/aydvvs.git //建立连接git remote -v //查看git add . //添加到暂存区git push 返送到暂存区git status // 查看提交代码git commit -m初次提交git push -u origin "master"//提交远程分支 …

微信小程序(五十二)开屏页面效果

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.使用控件模拟开屏界面 2.倒计时逻辑 3.布局方法 4.TabBar隐藏复现 源码&#xff1a; components/openPage/openPage.wxml <view class"openPage-box"><image src"{{imagePath}}"…