MySQL复合查询解析

news2024/11/15 13:26:48

在这里插入图片描述

🎈行百里者半九十🎈

🎈目录🎈

  • 概念
  • 多表查询
  • 自连接
  • 子查询
    • 单行子查询
    • 多行子查询
      • in关键字
      • all关键字
      • any关键字
    • 多列子查询
    • 在from中使用子查询
    • 合并查询
      • union
      • union all
  • 总结


概念

之前我们很多的查询都只是对于单表进行查询,而在实际开发中往往数据来自不同的表,所以需要多表查询。多表查询也称复合查询,MySQL复合查询是指在一个查询语句中结合使用多个子查询或联结(JOIN)操作,以完成更复杂的数据检索或分析任务。这种查询可以包括多个 SELECT 语句、联结、子查询等,从而允许你在一个查询中获取来自不同表的数据或根据不同条件组合结果。复合查询的主要目的是实现对数据库中数据的灵活检索,以便满足复杂的业务需求。

多表查询

基本的多表查询通常涉及使用 JOIN 操作,以联结两个或多个表的数据。以下是一个简单的多表查询的例子,有如下两张stucla表。

在这里插入图片描述
在这里插入图片描述
当我们不设任何条件单纯进行复合查询,执行语句会出现如下结果:

select * from stu, cla; ---select * from stu join cla;

在这里插入图片描述
可以看到在结果中,每个表的每一行都与另一个表的每一行组合,形成了笛卡尔积。在实际应用中,应当避免无条件的笛卡尔积,因为它可能导致结果集非常庞大,对性能产生负面影响。通常,应该通过使用合适的连接条件来执行表的连接,以获得更有意义的结果。

例如,获取每个人的姓名、性别和国家。

select stu.name '姓名', sex '性别', cla.name '国家' 
from stu, cla 
where stu.class=cla.id;

在这里插入图片描述

类似这样的多表查询可帮助你从关联的表中检索出合并的信息,使得查询结果更具有实际业务意义。

自连接

自连接是指在同一张表内进行连接操作,即连接表中的不同行与自身的其他行。这种连接通常涉及使用表的别名(alias)来区分表的不同实例。

如下示例,假设有一个表 employees 包含员工的信息,其中包括员工的ID和其直接上级的ID:
在这里插入图片描述

在这个表中,manager_id 列表示员工的直接上级的ID。要查询每个员工及其对应的直接上级,可以执行自连接,使用表的别名来引用相同的表:

select e1.name name, e2.name manager 
from employees e1, employees e2
where e1.manager_id=e2.employee_id;

在这里插入图片描述

在这个例子中,employees 表通过自连接找到每个员工及其对应的直接上级。通过使用表别名,我们可以清晰地区分表的两个实例,并指定连接条件。自连接通常用于处理层次结构数据,其中一个记录与同一表中的另一个记录有关联。

子查询

子查询是嵌套在主查询中的查询,可以作为主查询的一部分来获取需要的数据。子查询可以出现在不同的位置,例如在 SELECT、FROM、WHERE 子句中,根据需求选择合适的位置。

单行子查询

单行子查询是指返回单一值而不是结果集的子查询。这种类型的子查询通常用于在主查询中计算或比较单一值。例如假设有两个表 studentsgrades,其中 students 表包含学生信息,grades 表包含学生成绩信息。

students

在这里插入图片描述

grades

在这里插入图片描述

现在,假设我们想找到成绩最高的学生。我们可以使用单行子查询来获取最高分数:

select student_id, student_name
from students
where student_id = (select student_id from grades order by grade desc limit 1);

在这个查询中,子查询 (select student_id from grades order by grade desc limit 1) 返回最高分数对应的学生ID,然后主查询使用这个学生ID来获取相关的学生信息。结果如下:

在这里插入图片描述

多行子查询

多行子查询是指返回多个结果的子查询,通常用于与主查询中的某个条件进行比较或筛选。假设有两个表 employeessalaries,其中 employees 表包含员工信息,salaries 表包含员工薪资信息。

employees

在这里插入图片描述

salaries

在这里插入图片描述

现在,假设我们想找到薪资高于公司平均薪资的员工。我们可以使用多行子查询计算平均薪资并与每个员工的薪资进行比较:

select e.employee_id, employee_name, salary 
from employees e, salaries s 
where e.employee_id=s.employee_id and salary > (select avg(salary) from salaries);

在这个查询中,子查询 (select avg(salary) from salaries) 返回每个员工的平均薪资,然后主查询使用这些值来筛选薪资高于平均薪资的员工。结果如下:

在这里插入图片描述

in关键字

当使用 IN 关键字时,你可以通过指定一个值列表来检查某个列是否包含在这个值列表中。可以使用 IN 关键字检查 employee_id 是否在满足条件(薪资高于公司平均薪资)的员工列表中。

select e.employee_id, employee_name, salary 
from employees e, salaries s 
where e.employee_id = s.employee_id and e.employee_id in ( 
select employee_id from salaries where salary > ( 
select avg(salary) from salaries));

在这里插入图片描述

在这个查询中,IN 子句检查 employee_id 是否在子查询中返回的员工列表中。这个子查询会选择那些薪资高于公司平均薪资的员工的 employee_id。这样,你就可以得到所有薪资高于公司平均薪资的员工的记录。

all关键字

在 SQL 中,ALL 关键字用于与比较运算符一起使用,用于比较某个值与子查询中所有值的关系。通常,ALL 与比较运算符一起使用,例如 > ALL< ALL。假设有两个表,分别为学生信息和多个成绩的表格。

在这里插入图片描述

现在,我们想查询所有成绩都高于Bob的成绩的记录:

select s.student_id, s.student_name, g.subject, g.grade
from students s, grades g
where s.student_id = g.student_id and s.student_name <> 'bob'
and g.grade > all (select grade from grades where student_id = 3);

在这里插入图片描述

请注意,使用 ALL 关键字时,要确保子查询返回的结果不包含 NULL 值,否则可能导致不确定的结果。

any关键字

在 SQL 中,ANY 关键字用于与比较运算符一起使用,用于比较某个值与子查询中的任何值的关系。通常,ANY 与比较运算符一起使用,例如 > ANY< ANY。如上有两个表,分别为学生信息和多个成绩的表格。

在这里插入图片描述

接下来要查询返回至少有一门课程成绩高于某个特定学生(例如Bob)的成绩的学生记录:

select s.student_id, s.student_name, g.course, g.grade 
from students s, grades g
where s.student_id = g.student_id 
and s.student_name <> 'bob' and g.grade > any (
select grade from grades where student_id = 3);

在这里插入图片描述

注意,与 all 不同,any 表示与子查询中的任何值进行比较,all是满足所有才为真,any是满足其中之一就为真(类似C语言中的&&和||)。同样,要确保子查询返回的结果不包含 NULL 值,以避免不确定的结果。

多列子查询

多列子查询通常用于在子查询中检索多列数据,并与主查询中的多列数据进行比较。假设有两个表格:orders 表格和 order_items 表格,用于跟踪订单和订单项的信息。

在这里插入图片描述

接下来想要查找所有订单的客户以及他们的订单总金额,但只包括那些订单总金额高于平均订单总金额的客户。

select o.customer_id, 
       sum(oi.quantity * oi.price) as total_amount
from orders o, order_items oi
where o.order_id = oi.order_id
group by o.customer_id
having sum(oi.quantity * oi.price) > (
    select avg(order_total)
    from (
        select o.customer_id, 
               sum(oi.quantity * oi.price) as order_total
        from orders o, order_items oi
        where o.order_id = oi.order_id
        group by o.customer_id
    ) as subquery
);

在这里插入图片描述

在上面的查询中使用了多列子查询。子查询计算了每个客户的订单总金额,并将其与平均订单总金额进行比较。主查询选择了那些订单总金额高于平均订单总金额的客户。

在from中使用子查询

FROM 子句中使用子查询是一种高级 SQL 技巧,通常用于创建临时表或派生表格,以便在查询中进一步使用。这种方法常常用于解决复杂的数据处理和报表生成问题。例如在如上的两个表格中,表格 orders 记录了订单信息,以及一个表格 order_items 记录了订单项的信息。当我们想计算每个订单的总金额,并在查询结果中包括订单的其他信息。

在这里插入图片描述

接下来,我们在 FROM 子句中使用子查询来计算每个订单的总金额并包括其他订单信息:

select o.order_id, o.customer_id, o.order_date, total_amount
from orders o, (
    select oi.order_id, sum(oi.quantity * oi.price) as total_amount
    from order_items oi
    group by oi.order_id
) as order_totals
where o.order_id = order_totals.order_id;

在这里插入图片描述

在这个查询中,我们在 FROM 子句中使用了一个子查询,该子查询计算了每个订单的总金额(通过对 order_items 表进行汇总)。然后,我们将主查询中的 orders 表格与子查询的结果进行连接,以获取每个订单的总金额以及其他订单信息。我们在一个查询中创建一个临时表格(order_totals),并将其用于进一步的数据处理。

合并查询

合并查询通常指的是使用 UNIONUNION ALL 操作符将多个查询的结果合并为一个结果集,这在需要合并多个查询结果时非常有用。

union

UNION 是用于合并两个或多个 SELECT 查询结果集的 SQL 操作符。它将多个查询的结果合并为一个结果集,并自动去除重复的行(不会保留重复的行)。UNION 的语法如下:

SELECT column1, column2, ...
FROM table1
UNION
SELECT column1, column2, ...
FROM table2;

假设有两个表格 students_astudents_b,它们包含了两个班级的学生信息。我们可以使用 UNION 合并这两个班级的学生名单:

在这里插入图片描述

select student_name from students_a
union
select student_name from students_b;

在这个示例中,UNION 操作符合并了 students_astudents_b 表的学生名单,并返回不重复的学生名单。如果有学生出现在两个表中,只会在结果中出现一次。

在这里插入图片描述

union all

UNION ALL 是用于合并两个或多个 SELECT 查询结果集的 SQL 操作符,与 UNION 不同的是,它不会去除重复的行,而会保留所有行。UNION ALL 的语法如下:

SELECT column1, column2, ...
FROM table1
UNION ALL
SELECT column1, column2, ...
FROM table2;

与上面一样有两个表格 students_astudents_b,它们包含了两个班级的学生信息。我们使用 UNION ALL 合并这两个班级的学生名单:

select student_name from students_a
union all
select student_name from students_b;

在这里插入图片描述

示例中,UNION ALL 操作符合并了 students_astudents_b 表的学生名单,并返回包括重复学生名单的结果。如果有学生出现在两个表中,它们都会在结果中保留。

UNION 不同,UNION ALL 不执行去重操作,因此在某些情况下,它可能比 UNION 更快,特别是当你知道结果中不会有重复行时。但要注意,如果你需要去除重复的行并且只保留唯一的行,应该使用 UNION

总结

文章主要介绍了MySQL中的多表查询相关的知识点,掌握这些功能和技巧可用于执行复杂的数据操作和查询,以满足各种数据库需求。码文不易,如果文章对你有帮助的话就劳烦点一个👍,感谢支持!

在这里插入图片描述

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

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

相关文章

DMA技术在STM32中优化UART、SPI和I2C通信性能的研究与实现

DMA&#xff08;Direct Memory Access&#xff0c;直接存储器访问&#xff09;技术可以在STM32微控制器上优化UART、SPI和I2C等通信性能。DMA可以实现数据的高速传输&#xff0c;减轻CPU的负担&#xff0c;提高系统性能。在本篇文章中&#xff0c;我将探讨DMA技术在STM32中优化…

【C语言基础篇】结构控制(中)循环结构

文章目录 一、循环结构 1. while语句 2. for语句 3. do while语句 4. 循环结构总结 C语⾔是结构化的程序设计语⾔&#xff0c;这⾥的结构指的是顺序结构、选择结构、循环结构。也就是说在C语言所有的代码都是这三种结构。 本篇文章将会着重讲解循环结构 顺序结构和选…

数据结构图算法

算法就要多练,我在国庆节放假的时间编写了图的算法题,写完让我受益匪浅,希望可以帮助到大家. 文章目录 前言 一、图的数据结构 1.图的邻接表数据结构定义 2.图的邻接矩阵的存储形式 二、邻接表建立图代码 三、邻接表删除边(基本操作考试不考) 四、邻接表删除顶点及销毁整…

【MySQL进阶】索引

索引机制 索引介绍 MySQL 官方对索引的定义为&#xff1a;索引&#xff08;index&#xff09;是帮助 MySQL 高效获取数据的一种数据结构&#xff0c;**本质是排好序的快速查找数据结构。**在表数据之外&#xff0c;数据库系统还维护着满足特定查找算法的数据结构&#xff0c;这…

用el-image-viewer实现全局预览图片

背景 在后台管理系统中&#xff0c;一些预览图片的场景&#xff0c;通常都是使用 el-image-viewer 去实现&#xff0c;但是如果多个地方都需要预览图片&#xff0c;又要重复的去写 el-image-viewer 以及一些重复的和预览相关的代码。 可以把预览图片的组件放在根文件&#x…

洛谷P2615 [NOIP2015 提高组] 神奇的幻方(C语言)

这普及题太水了&#xff0c;你按照他给的条件来列判断语句。 按题目一步一步模拟 首先将1写在第一行的中间。 若K-1在第一行但不在最后一列&#xff0c;则将K填在最后一行&#xff0c;K-1所在列的右一列&#xff1b; 若K-1在最后一列但不在第一行&#xff0c;则将K填在第一…

深入解析与实践:Ajax异步请求在Web开发中的应用指南

一、概述 1、定义 ​ Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;异步请求是现代Web开发中不可或缺的技术组件&#xff0c;它允许网页在不刷新整个页面的情况下从服务器获取并更新数据&#xff0c;从而实现动态、流畅的交互体验。 2、异步和同步 浏览器访…

【NVIDIA】Jetson Orin Nano系列:安装 Qt6、firefox、jtop、flameshot

1、使用命令安装 sudo apt install qtcreator sudo apt install qt6-* sudo apt install libqt6* sudo apt install qml-qt6 sudo apt install qmlscene-qt6 sudo apt install assistant-qt6 sudo apt install designer-qt62、启动 qtcreator 3、常用工具安装 sudo apt in…

计算机找不到msvcp120.dll的修复方法,总结五种可靠的方法

在计算机使用过程中&#xff0c;遭遇“找不到msvcp120.dll”这一问题的困扰是许多用户都可能遇到的情况。这一特定的系统文件msvcp120.dll&#xff0c;作为Microsoft Visual C Redistributable Package的重要组成部分&#xff0c;对于运行某些应用程序至关重要。当系统提示无法…

如何在 Element Plus 中使用自定义 icon 组件 (非组件库内置icon)

先说原理就是将 svg 文件以 vue 组件文件的方式使用 需求&#xff1a;我想要在 Element Plus 得评分组件中使用自定义得图标。 el-rate v-model"value1" /> 组件本身是支持自定义图标的&#xff0c;但是教程中只说明了如何使用 element-plus/icons-vue 图标库内置…

学习Spring的第八天

先对自定义类使用MyComponet的注解&#xff0c;在设置这个MyComponet的的属性(一个 interface接口)&#xff0c;然后&#xff0c;扫描(BaseClassScanUtils.java执行,这文件不重要)当前包下是否有这个注解的类&#xff0c;再用MyComponentBeanFactoryPostProcessor.java(后工厂…

蓝桥杯真题(Python)每日练Day1

说明&#xff1a;在CSP认证的基础上&#xff08;可以看看本人CSP打卡系列的博客&#xff09;备赛2024蓝桥杯&#xff08;Python&#xff09;&#xff0c;本人专业&#xff1a;大数据与数据科学 因此对python要求熟练掌握&#xff0c;通过练习蓝桥杯既能熟悉语法又能锻炼算法和思…

vulnhub-dc2靶场

DC2 配置环境vmware17 nat网络配置 下载地址:DC and Five86 Series Challenges - DC-1 &#xff08;似乎从2024/1/18左右找不到这个资源了&#xff09; 攻击机kali与其在同一网段下 ip:192.168.52.130 信息收集 arp-scan -l #内网探测&#xff0c;扫描目标ip发现目标ip1…

内网穿透Neutrino-Proxy, 中微子代理

中微子代理&#xff08;neutrino-proxy&#xff09;是一个基于netty的、开源的java内网穿透项目。技术栈&#xff1a;Solon、MybatisPlus、Netty遵循MIT许可&#xff0c;因此您可以对它进行复制、修改、传播并用于任何个人或商业行为。官网地址1&#xff1a;https://neutrino-p…

鸿蒙开发环境配置-Windows

背景 入局鸿蒙开发&#xff0c;发现在 Windows 下面配置安装相关环境并没有像 Mac 一样简单&#xff0c;过程中遇到了一些问题记录一下。 Devceo Studio 下载安装 目前鸿蒙的 IDE 最新版是 4.0&#xff0c;通过这个连接可以下载&#xff0c;鸿蒙4.0下载连接。选择符合我们电…

关于前端面试中forEach方法的灵魂7问?

目录 前言 一、forEach方法支持处理异步函数吗&#xff1f; 二、forEach方法在循环过程中能中断吗&#xff1f; 三、forEach 在删除自己的元素后能重置索引吗&#xff1f; 四、forEach 的性能相比for循环哪个好&#xff1f; 五、使用 forEach 会不会改变原来的数组&#…

智能驾驶新浪潮:SSD与UFS存储技术如何破浪前行?-UFS篇

如果说SSD是赛道上的超级跑车&#xff0c;那UFS更像是专为智能汽车定制的高性能轻量化赛车。UFS采用串行接口技术&#xff0c;像是闪电侠一样&#xff0c;将数据传输的速度推向新高&#xff0c;大幅缩短了系统启动时间和应用程序加载时间&#xff0c;这对追求即时反应的ADAS系统…

【从零开始学习Java重要知识 | 第三篇】暴打ReentrantLock底层源码

目录 前言&#xff1a; 前置知识&#xff1a; 什么是公平锁与非公平锁&#xff1f; 尝试自己构造一把锁&#xff1a; ReentrantLock源码&#xff1a; 加锁&#xff1a; 解锁&#xff1a; 总结&#xff1a; 前言&#xff1a; 在并发编程中&#xff0c;线程安全是一个重…

【轮式平衡机器人】——软硬件配置/准备

本系列以轮式平衡移动机器人为例&#xff0c;将使用基于模型设计&#xff08;MBD&#xff09;方法进行介绍&#xff0c;涉及基础硬件、软件、控制算法等多方面内容&#xff0c;结合MATLAB/Simulink的强大仿真能力和代码生成能力辅助设计&#xff01;在此过程中可以系统了解开发…

SpringBoot+dynamic-datasource实现多数据源(msyql、sqlserver、postgresql)手动切换

场景 SpringBootMybatisPlusdynamic-datasources实现连接Postgresql和mysql多数据源&#xff1a; SpringBootMybatisPlusdynamic-datasources实现连接Postgresql和mysql多数据源-CSDN博客 上面实现通过注解和配置文件的方式去进行多数据源操作。 如果业务需求&#xff0c;比…