MySQL数据库复合查询

news2024/9/24 21:20:49

文章目录

  • 一、多表查询
  • 二、自连接
  • 三、子查询
    • 1.单行子查询
    • 2.多行子查询
    • 3.多列子查询
    • 4.在from子句中使用子查询
  • 四、合并查询

一、多表查询

在实际开发中,我们需要查询的数据往往会来自不同的表,所以需要进行多表查询。下面我们用一个简单的公司管理系统,有emp、dept、salgrade三张表,来演示如何进行多表查询。

案例一:
显示雇员名、雇员工资以及所在部门的名字。

由于雇员名和雇员工资在emp表中,雇员所在的部门在dept表中,所以需要进行两张表的联合查询。

在这里插入图片描述

MySQL的select语句其实不是一次只能查询一张表,它可以一次性查询多张表,表与表之间用逗号隔开,例如我们想要查找emp表和dept表,输入指令select * from emp,dept;即可查询到两张表的组合:

在这里插入图片描述

上表的组合方式是,先从第一张表即emp表中选出第一条记录,和第二张表即dept表中的所有记录进行组合。然后从第一张表中选第二条记录,和第二张表中的所有记录进行组合。不加过滤条件,最后得到的结果称为笛卡尔积。

多表查询,将多张表的结果进行组合,形成笛卡尔积,它的本质是对表中所有数据的穷举。既然我们得到了这些笛卡尔积,有了所有数据组合的穷举内容,那么我们就可以添加过滤条件,筛选出我们需要查询的数据。

回到案例中的题面,它需要我们查询雇员名和雇员工资以及所在部门的名字,但是我们将两张表组合出来的时候,会出现两个deptno字段,只有两个的deptno相等的数据才是我们需要的。所以我们需要首先筛选出这样的数据,输入指令select * from emp,dept where emp.deptno = dept.deptno;即可。

在这里插入图片描述

最后我们再筛选出雇员姓名、工资以及所在部门,输入指令select ename, sal, dname from emp, dept where emp.deptno = dept.deptno;即可。

在这里插入图片描述

案例二:
显示部门号为10的部门名、员工名和工资。

这道题也不难,只需要再加上部门号为10这一限制条件即可,输入指令select ename, sal, dname from emp, dept where emp.deptno = dept.deptno and dept.deptno = 10;即可。

在这里插入图片描述

二、自连接

同一张表自己和自己连接称为自连接,指的是在同一张表中连接查询。也就是说依旧是使用多表查询,只不过查询的两张表是同一张表。我们可以尝试一下,输入指令select * from emp, emp;,我们会发现报错了,查询不了。原因是两张相同的表有重复的冲突元素。

在这里插入图片描述
解决这个问题,我们可以将两张相同的表分别重命名为两个不一样的名字,输入指令select * from emp as e1, emp as e2;

在这里插入图片描述

这样就实现了自连接查询。假如我们想在emp表中查询员工FORD的上级领导的编号和姓名,使用自连接查询,其中mgr是员工领导的编号,所以我们首先要查找员工领导编号mgr和该员工自己的编号empno相等的数据,输入指令select * from emp e1, emp e2 where e1.mgr = e2.empno;

在这里插入图片描述

接下来我们需要在上面查询结果的基础上,再添加员工名为FORD的限制条件,因为我们是要查询FORD员工的上级领导编号和姓名,输入指令select * from emp e1, emp e2 where e1.mgr = e2.empno and e1.ename = 'FORD';

在这里插入图片描述

最后再查询FORD上级领导的编号和姓名,输入指令:
select e2.ename, e2.empno from emp e1, emp e2 where e1.mgr = e2.empno and e1.ename = 'FORD';

在这里插入图片描述

三、子查询

子查询是指嵌入在其它SQL语句中的select语句,也叫作嵌套查询。子查询分为单行子查询和多行子查询。

1.单行子查询

例如我们想要查询在emp表中和SMITH同一部门的员工,使用子查询的话,可以将SMITH的部门编号拿出来,再与表中所有员工的部门编号进行对比,找出与SMITH部门编号相同的员工。输入语句select * from emp where deptno = (select deptno from emp where ename = 'SMITH');

在这里插入图片描述

2.多行子查询

单行子查询有时候不能满足我们的需求,一般我们需要使用多行子查询。多行子查询是可以返回多行记录的子查询,多行子查询需要用到in关键字、all关键字、any关键字,下面分别介绍这三个关键字的使用。

in关键字
in关键字的基本语法如下,列名+in后面跟一条select语句的子查询,它代表的是只要列名在后面子查询的集合中,就显示出来。

列名 in (select ......)

例如我们想要在emp表中查询和10号部门的工作岗位相同的雇员的名字、岗位、工资和部门号,但是不包括10号部门自己的。

做这道题首先可以查找出emp表中部门号为10的所有员工的工作岗位,输入语句select distinct job from emp where deptno = 10;

在这里插入图片描述
选择出来之后,我们再用in关键字,选择出job列属于上述结果的员工,显示他们的名字、岗位、工资和部门号,输入语句select ename, job, sal, deptno from emp where job in (select distinct job from emp where deptno = 10);

在这里插入图片描述

最后,题目要求查询结果不包括部门编号为10本身,所以我们可以再将上述查找出的结果加上deptno不等于10的限制条件即可。输入语句select ename, job, sal, deptno from emp where (job in (select distinct job from emp where deptno = 10)) and (deptno != 10);

在这里插入图片描述

all关键字
all关键字的基本语法和in关键字一样,all后面跟一条select语句的子查询,它代表的是选出select语句集合中的所有元素。例如我们想要显示工资比部门30的所有员工的工资高的员工姓名、工资和部门号,输入语句select ename, sal, deptno from emp where sal > all(select sal from emp where deptno=30);这里使用的all关键字,代表的意思是从emp表中选择薪资大于后面子查询集合的所有工资。

在这里插入图片描述

any关键字
any关键字的使用和all关键字的使用相似,只不过二者在含以上有区别。举个例子,如果我们要选择比所有学生成绩都高的学生,就要使用all关键字。如果我们要选择比任意一个学生成绩都高的学生,就要使用any关键字。all关键字选择出来的一定是比集合里最高成绩的学生还要高的,any关键字选择出来的只要比集合里最低成绩的学生还要高的就可以了。

例如我们想在emp表中显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门的员工),输入语句select ename, sal, deptno from emp where sal > any (select sal from emp where deptno = 30);

在这里插入图片描述

3.多列子查询

单行子查询是指子查询返回的集合中只会是单列单行的数据,例如上面说的查询和SMITH同一部门的员工,子查询返回的是SMITH的部门编号,是单列单行数据。多行子查询是指子查询返回的集合中是单列多行的数据,例如上面说的查询和10号部门的工作岗位相同的雇员名字、岗位、工资和部门号,子查询返回的是部门号为10的所有员工的工作岗位,是单列多行数据。而多列子查询是指子查询返回的是多个列的数据。

例如我们想要查询和SMITH的部门和岗位完全相同的所有雇员,不包含SMITH本人。

这个题目首先要查出SMITH的部门和岗位,输入语句select job, deptno from emp where ename = 'SMITH';

在这里插入图片描述
然后我们查询和SMITH的部门和岗位完全相同的所有雇员,多列查询可以使用如下类型的语句:select * from emp where (job, deptno) = (select job, deptno from emp where ename = 'SMITH');

在这里插入图片描述
最后,由于题目要求查询结果不包含SMITH,所以输入语句select * from emp where ((job, deptno) = (select job, deptno from emp where ename = 'SMITH')) and ename != 'SMITH';

在这里插入图片描述

4.在from子句中使用子查询

我们前面用到的子查询都是放在where子句中,from子句中也可以使用子查询。这里要用到数据查询的一个技巧,即把一个子查询当作一个临时表来使用。

例如,我们想显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资。

这道题目我们逐层分解的话,首先需要查询到各个部门的平均工资,输入语句select avg(sal) asal, deptno from emp group by deptno;

在这里插入图片描述

查询到结果之后,我们将上述结果当成一张临时表,与原来的emp表做笛卡尔积,输入语句select * from emp, (select avg(sal) asal, deptno from emp group by deptno) tmp;

在这里插入图片描述

这样就得到了所有的组合结果,但是我们发现这上面的组合结果中有一些是不符合实际的数据,我们还需要进一步筛选,筛选出emp表的deptno和tmp表中deptno相等的数据,才是符合实际的。输入语句select * from emp, (select avg(sal) asal, deptno from emp group by deptno) tmp where emp.deptno = tmp.deptno;

在这里插入图片描述

最后,我们可以在上面查找到的表中进一步查询,查询高于自己部门平均工资的员工的姓名、部门、工资和平均工资。输入语句select emp.ename, emp.deptno, emp.sal, format(asal, 2) myavg from emp, (select avg(sal) asal, deptno from emp group by deptno) tmp where (emp.deptno = tmp.deptno) and emp.sal > tmp.asal;

在这里插入图片描述

四、合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符union和union all来合并。union操作符用于取得两个结果集的并集,当使用该操作符时,会自动去掉结果集中的重复行。union all操作符也是用于取得两个结果集的并集,但使用该操作符时,不会去掉结果集中的重复行。

例如,我们想要查找emp表中工资大于2500或者职位是MANAGER的人,分别使用union和union all操作符看看效果:

select * from emp where sal > 2500 union select * from emp where job = 'MANAGER';
select * from emp where sal > 2500 union all select * from emp where job = 'MANAGER';

在这里插入图片描述

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

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

相关文章

启动游戏提示缺少(或丢失)xinput1_3.dll的解决办法

在我们打开游戏的或者软件的时候,电脑提示“找不到xinput1_3.dll,无法继续执行此代码”怎么办?相信困扰着不少小伙伴,我再在打开吃鸡的时候,然后花了一上午的时候时间研究,现在终于知道xinput1_3.dll文件是…

基于TCP协议实现多人在线的聊天室

基于TCP协议实现多人在线的聊天室 程序采用CS架构,功能支持注册,登录,退出,私聊,群聊,查看历史信息。属于Java Swing窗口程序。 技术:Java swing,mysql 开发工具:IDEA…

性能测试之全链路压测流量模型你了解多少

目录 前言 基于业务模型实现 基于流量录制回放 灰度分流 总结: 前言 现在全链路越来越火,各大厂商也纷纷推出了自己的全链路压测测试方案。特别是针对全链路压测流量模型,各家方案都有所不同。最近我看了一些这方面的资料,有…

万能的网关系统设计方案,一篇带走

本文准备围绕七个点来讲网关,分别是网关的基本概念、网关设计思路、网关设计重点、流量网关、业务网关、常见网关对比,对基础概念熟悉的朋友可以根据目录查看自己感兴趣的部分。 什么是网关 网关,很多地方将网关比如成门, 没什么…

mac pro m1:搭建zookeeper集群并设置开机自启

0. 引言 之前我们讲解过搭建zookeeper单节点,但在实际生产中,为了保证服务高可用,通常我们是采用集群模式。所以本次我们来实操集群模式的搭建 1. zk集群模式 zk可以作为注册中心和配置中心,常用在微服务各类组件的多节点服务治…

Tomcat优化及部署

目录 一、Tomcat概述 二、Tomcat核心组件 1.Web容器 2.servlet容器 3.JSP容器 三、Tomcat的功能组件 1.connector 2.container 3.service 四、Tomcat部署 1.关闭防火墙和安全机制 2.将安装 Tomcat 所需软件包传到/opt目录下 3.安装JDK 4.设置JDK环境变量 5.编写j…

链路性能测试中参数多样性方法分享

目录 业务无关量 随机数字 线程安全随机 随机字符串 业务相关量 随机相关量 上游接口获取 上游接口造数据 提前造数据 总结: 下面分享几种我工作中常用到的增加参数多样性的方法。 业务无关量 这个是最常用到的,当部分的接口参数对接下来的用…

机器人开发--EKF扩展卡尔曼滤波介绍

机器人开发--EKF卡尔曼滤波介绍 1 介绍1.1 概述KF (Kalman Filter)EKF (Extended Kalman Filter)UKF (Unscented Kalman Filter) 1.2 发展历史1.3 卡尔曼演化分支1.4 应用1.5 特点1.6 姿态估计问题 from 南叔先生1.7 EKF、PF、UKF 对比1.8 EKF 递归框架 2 理解機器人學&#xf…

使用Matplotlib画三维图

使用matplotlib画3D图: import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D# 创建X和Y的网格点 x np.linspace(-5, 5, 100) y np.linspace(-5, 5, 100) X, Y np.meshgrid(x, y)# 创建Z的网格点(这里使用一…

nginx 配置m3u8播放视频

第一步nginx配置: 参考 csdn - CircleMouse Nginx配置搭建m3u8格式的视频播放服务 user www www; worker_processes auto; error_log /www/wwwlogs/nginx_error.log crit; pid /www/server/nginx/logs/nginx.pid; worker_rlimit_nofile 51200;stream {l…

提高情商的训练方法

在当今社会,情商已经成为了一个越来越受到重视的概念。情商指的是一个人在情感方面的智力水平,即情绪智商,包括了自我意识、自我管理、社交意识和关系管理等多个方面。而提高情商并非是天生的天赋,而是可以通过学习和实践获得的技…

自然语言处理从入门到应用——预训练模型总览:词嵌入的两大范式

分类目录:《自然语言处理从入门到应用》总目录 相关文章: 预训练模型总览:从宏观视角了解预训练模型 预训练模型总览:词嵌入的两大范式 预训练模型总览:两大任务类型 预训练模型总览:预训练模型的拓展 …

【论文解读系列】MLLM研究综述

A Survey on Multimodal Large Language Models 1 中国科大科技学院、认知智能国家重点实验室 2 腾讯优图实验室 MLLM目录 0. 摘要1. 引言2. 总览3. 方法3.1 多模态指令调谐3.1.1 引言3.1.2 前言(Preliminaries)3.1.3 模态对齐3.1.4 数据3.1.5 模态桥接3.1.6 评估 3.2 多模态…

深入理解 Golang: 网络编程

Go 中的 Epoll 关于计算机网络分层与 TCP 通信过程过程此处不再赘述。 考虑到 TCP 通信过程中各种复杂操作,包括三次握手,四次挥手等,多数操作系统都提供了 Socket 作为 TCP 网络连接的抽象。Linux -> Internet domain socket -> SOC…

layui中文、以及图标乱码解决方案

最终解决方案…手动对js文件中的中文,用unicode进行编码

修改 ChatGLM2-6B 自我认知的 Lora 微调教程

修改 ChatGLM2-6B 自我认知的 Lora 微调教程 0. 背景1. 部署微调项目2. 数据集说明3. 模型监督微调(Lora)4. 模型效果测试5. 导出微调模型6. 调用导出的模型 0. 背景 现在开始学习微调,主要学习 Lora 微调。 这次尝试了修改 ChatGLM2-6B 自我认知,文章…

2023.7.2-【for语言】:输入一个整数,并输入该整数对应个数的整数,求他们的和与平均值

程序&#xff1a; int a;int b0;int c;int sum0;double ave;printf("请输入待求整数的个数&#xff1a;");scanf("%d",&a);for (b 1; b<a; b){printf("整数%d&#xff1a;", b);scanf("%d", &c);sum c;}printf("以上…

vite中的env环境变量

一、vite中使用env环境变量基本介绍 Vite 是一种现代化的前端构建工具&#xff0c;旨在提供快速的开发和构建体验。在 Vite 中&#xff0c;env 环境变量是一种用于在项目中设置和访问全局变量的机制。通过 env 变量&#xff0c;可以在不同环境下配置不同的参数&#xff0c;实现…

时间序列分解 | Matlab 互补集合经验模态分解(CEEMD)的信号分解

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 时间序列分解 | Matlab 互补集合经验模态分解(CEEMD)的信号分解 部分源码 %---------------------

Java基础---为什么不能用浮点数表示金额

目录 缘由 十进制转二进制 不是所有数都能用二进制表示 IEEE 754 避免精度丢失 缘由 因为不是所有的小数都能用二进制表示&#xff0c;所以&#xff0c;为了解决这个问题&#xff0c;IEEE提出了一种使用近似值表示小数的方式&#xff0c;并且引入了精度的概念这就是我们所…