当前位置: 首页 > news >正文

Mysql--基础篇--多表查询(JOIN,笛卡尔积)

在MySQL中,多表查询(也称为联表查询或JOIN操作)是数据库操作中非常常见的需求。通过多表查询,你可以从多个表中获取相关数据,并根据一定的条件将它们组合在一起。MySQL支持多种类型的JOIN操作,每种JOIN都有不同的用途和行为。

1、JOIN的基本概念

JOIN是一种用于从多个表中检索数据的操作。它允许你根据某些条件将两个或多个表中的行组合在一起。JOIN操作的核心思想是基于表之间的关联字段(通常是外键)来匹配行,并返回符合条件的结果集。

(1)、关联字段

  • 主键(Primary Key):唯一标识表中每一行的字段。
  • 外键(Foreign Key):一个表中的字段,引用另一个表的主键。外键用于建立表与表之间的关系。

(2)、JOIN类型

MySQL支持以下几种主要的JOIN类型:

  • 内连接(INNER JOIN):只返回两个表中满足连接条件的行。
  • 左连接(LEFT JOIN):返回左表中的所有行,即使右表中没有匹配的行,结果集中右表的列将填充为NULL。
  • 右连接(RIGHT JOIN):返回右表中的所有行,即使左表中没有匹配的行,结果集中左表的列将填充为NULL。
  • 全外连接(FULL OUTER JOIN):返回两个表中的所有行,无论是否满足连接条件。MySQL 不直接支持FULL OUTER JOIN,但可以通过UNION实现类似的效果。
  • 交叉连接(CROSS JOIN):返回两个表的笛卡尔积,即每个表中的每一行都与另一个表中的每一行组合。

2、JOIN的语法

(1)、内连接(INNER JOIN)

内连接是最常用的JOIN类型,它只返回两个表中满足连接条件的行。

示例:
假设我们有两个表employees和departments,其中employees表包含员工信息,departments表包含部门信息。employees表中的department_id字段是外键,引用了departments表的id字段。
sql:

-- 查询所有有部门的员工及其所属部门名称
SELECT employees.name, departments.name AS department_name
FROM employees
INNER JOIN departments ON employees.department_id = departments.id;

结果:
只返回那些有对应部门的员工信息。如果某个员工没有分配到任何部门,则该员工不会出现在结果集中。

(2)、左连接(LEFT JOIN)

左连接返回左表中的所有行,即使右表中没有匹配的行。对于右表中没有匹配的行,结果集中右表的列将填充为NULL。

示例:
查询所有员工及其所属部门名称,即使某些员工没有分配到部门
sql:

SELECT employees.name, departments.name AS department_name
FROM employees
LEFT JOIN departments ON employees.department_id = departments.id;

结果:
返回所有员工的信息。对于没有分配到部门的员工,department_name列将显示为NULL。

(3)、右连接(RIGHT JOIN)

右连接返回右表中的所有行,即使左表中没有匹配的行。对于左表中没有匹配的行,结果集中左表的列将填充为NULL。

示例:
查询所有部门及其员工,即使某些部门没有员工
sql:

SELECT employees.name, departments.name AS department_name
FROM employees
RIGHT JOIN departments ON employees.department_id = departments.id;

结果:
返回所有部门的信息。对于没有员工的部门,employees.name 列将显示为 NULL。

(4)、全外连接(FULL OUTER JOIN)

全外连接返回两个表中的所有行,无论是否满足连接条件。MySQL不直接支持FULL OUTER JOIN,但可以通过 UNION 实现类似的效果。

示例:
查询所有员工及其所属部门,以及所有部门及其员工
sql:

SELECT employees.name, departments.name AS department_name
FROM employees
LEFT JOIN departments ON employees.department_id = departments.id
UNION
SELECT employees.name, departments.name AS department_name
FROM employees
RIGHT JOIN departments ON employees.department_id = departments.id;

结果:
返回所有员工和部门的信息。对于没有分配到部门的员工,department_name列将显示为NULL;对于没有员工的部门,employees.name列将显示为NULL。

(5)、交叉连接(CROSS JOIN)

交叉连接返回两个表的笛卡尔积,即每个表中的每一行都与另一个表中的每一行组合。

示例:
查询所有员工与所有部门的组合
sql:

SELECT employees.name, departments.name AS department_name
FROM employees
CROSS JOIN departments;

结果:
返回每个员工与每个部门的组合,结果集的行数等于employees表的行数乘以 departments表的行数。
在这里插入图片描述

3、多表查询的高级用法

(1)、多表JOIN

你可以在一个查询中连接多个表。只需在FROM子句中依次添加多个JOIN语句即可。

示例:
假设我们有三个表:employees(员工表)、departments(部门表)和salaries(工资表)。我们希望查询每个员工的姓名、所属部门名称以及他们的工资。
sql:

SELECT employees.name, departments.name AS department_name, salaries.salary
FROM employees
INNER JOIN departments ON employees.department_id = departments.id
INNER JOIN salaries ON employees.id = salaries.employee_id;

结果:
返回每个员工的姓名、所属部门名称以及他们的工资。

(2)、自连接(Self Join)

自连接是指一个表与自身进行连接。这通常用于处理具有层次结构的数据,例如员工的上下级关系。

示例:
假设employees表中有一个manager_id字段,表示每个员工的上级领导。我们希望查询每个员工及其上级领导的姓名。
sql:

SELECT e1.name AS employee_name, e2.name AS manager_name
FROM employees e1
LEFT JOIN employees e2 ON e1.manager_id = e2.id;

结果:
返回每个员工及其上级领导的姓名。对于没有上级领导的员工,manager_name列将显示为NULL。

(3)、子查询(Subquery)

子查询是指在一个查询中嵌套另一个查询。子查询可以用于过滤、聚合等操作。

示例:
假设我们想查询工资高于平均工资的员工。
sql:

SELECT employees.name, salaries.salary
FROM employees
INNER JOIN salaries ON employees.id = salaries.employee_id
WHERE salaries.salary > (SELECT AVG(salary) FROM salaries);

结果:
返回工资高于平均工资的员工及其工资。

4、JOIN的性能优化

多表查询可能会对性能产生影响,尤其是在处理大量数据时。为了提高多表查询的性能,可以采取以下几种优化措施:

(1)、索引优化

  • 确保连接字段上有索引:在JOIN操作中,连接条件中的字段(如外键)应该有索引。索引可以显著提高查询的执行速度。

  • 覆盖索引:如果查询中涉及的列都在索引中,MySQL可以直接从索引中获取数据,而不需要访问实际的表数据。这种情况下,查询性能会大幅提升。

(2)、避免不必要的列

  • 只选择需要的列:在SELECT语句中,尽量只选择你需要的列,而不是使用 SELECT *。这样可以减少I/O操作,提升查询性能。

(3)、使用适当的JOIN类型

  • 选择合适的JOIN类型:根据业务需求选择合适的JOIN类型。例如,如果你只需要查询满足条件的行,使用INNER JOIN;如果你需要保留所有行,使用LEFT JOIN或RIGHT JOIN。

(4)、分页查询

  • 使用分页查询:如果你只需要查询部分数据,可以使用LIMIT和OFFSET进行分页查询,避免一次性加载大量数据。

示例:

SELECT employees.name, departments.name AS department_name
FROM employees
INNER JOIN departments ON employees.department_id = departments.id
LIMIT 10 OFFSET 0;

结果:
返回前 10 条记录。

(5)、EXPLAIN分析查询计划

  • 使用EXPLAIN分析查询计划:通过EXPLAIN关键字,可以查看MySQL如何执行查询,帮助你发现潜在的性能问题。EXPLAIN会显示查询的执行计划,包括使用的索引、扫描的行数等信息。

示例:

EXPLAIN SELECT employees.name, departments.name AS department_name
FROM employees
INNER JOIN departments ON employees.department_id = departments.id;

结果:
返回查询的执行计划,帮助你分析查询的性能瓶颈。

5、常见问题及解决方案

(1)、笛卡尔积问题

  • 问题描述:如果不指定连接条件,JOIN操作可能会导致笛卡尔积,即每个表中的每一行都与另一个表中的每一行组合,结果集的行数可能非常大。

  • 解决方案:始终确保在JOIN操作中指定明确的连接条件,避免笛卡尔积的发生。

(2)、N+1查询问题

  • 问题描述:是指在执行一次查询后,又触发了多个额外的查询,导致查询次数大幅增加,影响数据库性能。这种情况通常发生在ORM(对象关系映射)框架中。如获取所有人员所在部门信息,N+1问题就是:先查询主表中所有的人员,在遍历所有人员去查询部门表。

  • 解决方案:使用JOIN进行批量查询:将主表和子表的数据一次性查询出来,避免N+1造成多次查询问题。

(3)、重复数据问题

  • 问题描述:在某些复杂的JOIN操作中,可能会出现重复数据。例如,当一个表中有多个匹配的行时,结果集中可能会出现重复的记录。

  • 解决方案:使用DISTINCT关键字去除重复数据,或者调整JOIN条件,确保结果集中没有重复的行。

示例:

SELECT DISTINCT employees.name, departments.name AS department_name
FROM employees
INNER JOIN departments ON employees.department_id = departments.id;

结果:
返回不重复的员工及其所属部门名称。

6、总结

  • JOIN是MySQL中用于从多个表中检索数据的强大工具。通过不同的JOIN类型(如INNER JOIN、LEFT JOIN、RIGHT JOIN等),你可以根据业务需求灵活地组合多个表的数据。
  • 性能优化是多表查询中不可忽视的一部分。通过合理的索引设计、选择合适的JOIN类型、避免不必要的列以及使用EXPLAIN分析查询计划,可以显著提升查询的性能。
  • 常见问题(如笛卡尔积、N+1查询、重复数据等)需要特别注意,并采取相应的解决方案。

相关文章:

Mysql--基础篇--多表查询(JOIN,笛卡尔积)

在MySQL中,多表查询(也称为联表查询或JOIN操作)是数据库操作中非常常见的需求。通过多表查询,你可以从多个表中获取相关数据,并根据一定的条件将它们组合在一起。MySQL支持多种类型的JOIN操作,每种JOIN都有…...

Java 泛型的用法

1. 泛型类 泛型类是指在类定义时使用类型参数来指定类的类型。这样可以在类的内部使用这些类型参数来定义字段、方法的返回类型和参数类型。 public class Box<T> {private T t;public void set(T t) {this.t t;}public T get() {return t;} }在这个例子中&#xff0c…...

人工智能与物联网:智慧城市的未来

引言 清晨6点&#xff0c;智能闹钟根据你的睡眠状态和天气情况&#xff0c;自动调整叫醒时间&#xff1b;窗帘缓缓打开&#xff0c;阳光洒满房间&#xff1b;厨房里的咖啡机已经为你准备好热饮&#xff0c;而无人驾驶公交车正按时抵达楼下站点。这不是科幻电影的场景&#xff…...

Python标准库之SQLite3

包含了连接数据库、处理数据、控制数据、自定义输出格式及处理异常的各种方法。 官方文档&#xff1a;sqlite3 --- SQLite 数据库的 DB-API 2.0 接口 — Python 3.13.1 文档 官方文档SQLite对应版本&#xff1a;3.13.1 SQLite主页&#xff1a;SQLite Home Page SQL语法教程&a…...

力扣 二叉树的最大深度

树的遍历&#xff0c;dfs与bfs基础。 题目 注意这种题要看根节点的深度是0还是1。 深度优先遍历dfs&#xff0c;通过递归分别计算左子树和右子树的深度&#xff0c;然后返回左右子树深度的最大值再加上 1。递归会一直向下遍历树&#xff0c;直到达到叶子节点或空节点。在回溯…...

Linux_进程间通信_共享内存

什么是共享内存&#xff1f; 对于两个进程&#xff0c;通过在内存开辟一块空间&#xff08;操作系统开辟的&#xff09;&#xff0c;进程的虚拟地址通过页表映射到对应的共享内存空间中&#xff0c;进而实现通信&#xff1b;物理内存中的这块空间&#xff0c;就叫做共享内存。…...

ubuntu 下生成 core dump

在Ubuntu下,发现程序崩溃后不生成core dump文件, 即使设置了ulimit -c unlimited后仍然无效。 1.ulimit -c unlimited 输出的的含义是核心转储文件的大小限制,单位是blocks,默认是0,表示不生成core dump文件。 2. 重设core_pattern ulimit -c unlimited后,核心转储文件…...

学习HLS.js

前言 HTTP 实时流&#xff08;也称为HLS&#xff08;.m3u8&#xff09;&#xff09;是一种基于HTTP的自适应比特率流通信协议。HLS.js依靠HTML5视频和MediaSource Extensions进行播放&#xff0c;其特点&#xff1a;视频点播和直播播放列表、碎片化的 MP4 容器、加密媒体扩展 …...

2025年华为OD上机考试真题(Java)——判断输入考勤信息能否获得出勤奖

题目&#xff1a; 公司用一个字符串来表示员工的出勤信息&#xff1a; absent&#xff1a;缺勤late&#xff1a;迟到leaveearly&#xff1a;早退present&#xff1a;正常上班 现需根据员工出勤信息&#xff0c;判断本次是否能获得出勤奖&#xff0c;能获得出勤奖的条件如下&am…...

空对象模式

在空对象模式&#xff08;Null Object Pattern&#xff09;中&#xff0c;一个空对象取代 NULL 对象实例的检查。Null 对象不是检查空值&#xff0c;而是反应一个不做任何动作的关系。这样的 Null 对象也可以在数据不可用的时候提供默认的行为。 在空对象模式中&#xff0c;我…...

开启Excel导航仪,跨表跳转不迷路-Excel易用宝

都2025年了&#xff0c;汽车都有导航了&#xff0c;你的表格还没有导航仪吗&#xff1f;那也太OUT了。 面对着一个工作簿中有N多个工作表&#xff0c;工作表中又有超级表&#xff0c;数据透视表&#xff0c;图表等元素&#xff0c;如何快速的切换跳转到需要查看的数据呢&#…...

年度技术突破奖|中兴微电子引领汽车芯片新变革

随着以中央计算区域控制为代表的新一代整车电子架构逐步成为行业主流&#xff0c;车企在电动化与智能化之后&#xff0c;正迎来以架构创新为核心的新一轮技术竞争。中央计算SoC&#xff0c;作为支撑智驾和智舱高算力需求的核心组件&#xff0c;已成为汽车电子市场的重要新增量。…...

Ubuntu 如何查看盘是机械盘还是固态盘

在 Ubuntu 系统中&#xff0c;您可以通过以下方法来确定硬盘是机械硬盘&#xff08;HDD&#xff09;还是固态硬盘&#xff08;SSD&#xff09;&#xff1a; 使用 lsblk 命令&#xff1a; 打开终端&#xff0c;输入以下命令&#xff1a; lsblk -d -o name,rota该命令将列出所…...

计算机网络(三)——局域网和广域网

一、局域网 特点&#xff1a;覆盖较小的地理范围&#xff1b;具有较低的时延和误码率&#xff1b;使用双绞线、同轴电缆、光纤传输&#xff0c;传输效率高&#xff1b;局域网内各节点之间采用以帧为单位的数据传输&#xff1b;支持单播、广播和多播&#xff08;单播指点对点通信…...

STM32F4分别驱动SN65HVD230和TJA1050进行CAN通信

目录 一、CAN、SN65HVD230DR二、TJA10501、TJA1050 特性2、TJA1050 引脚说明 三、硬件设计1、接线说明2、TJA1050 模块3、SN65HVD230 模块 四、程序设计1、CAN_Init&#xff1a;CAN 外设初始化函数2、CAN_Send_Msg、CAN_Receive_Msg 五、功能展示1、接线图2、CAN 数据收发测试 …...

将光源视角的深度贴图应用于摄像机视角的渲染

将光源视角的深度贴图应用于摄像机视角的渲染是阴影映射&#xff08;Shadow Mapping&#xff09;技术的核心步骤之一。这个过程涉及到将摄像机视角下的片段坐标转换到光源视角下&#xff0c;并使用深度贴图来判断这些片段是否处于阴影中。 1. 生成光源视角的深度贴图 首先&…...

docker一键安装脚本(docker安装)

第一种方法一键安装命令 curl -O --url http://luyuanbo79.south.takin.cc/wenjian/docker_install.sh && chmod x docker_install.sh && ./docker_install.sh 备用方法 curl -O --url https://file.gitcode.com/4555247/releases/untagger_0896d4789937405…...

【SY2】Apollo10.0 Cyber基于Writer/Reader的通信方式

实验前提 Apollo10.0已经安装完毕Vscode及相关插件安装完成启动容器并进入在Vscode连接进入到Apollo工作空间下学习资料 部分配置如实验一https://blog.csdn.net/weixin_60062799/article/details/145029669?spm1001.2014.3001.5501 学习资料 Apollo7.0或其他版本可以参…...

【YOLOv8杂草作物目标检测】

YOLOv8杂草目标检测 算法介绍模型和数据集下载 算法介绍 YOLOv8在禾本科杂草目标检测方面有显著的应用和效果。以下是一些关键信息的总结&#xff1a; 农作物幼苗与杂草检测系统&#xff1a;基于YOLOv8深度学习框架&#xff0c;通过2822张图片训练了一个目标检测模型&#xff…...

在Java中实现集合排序

使用字面量的方式创建一个集合 //使用字面量的方式初始化一个List集合List<User> userList Arrays.asList(new User("小A",5),new User("小鑫",18),new User("小昌",8),new User("小鑫",8));注意&#xff1a;使用Arrays.asLis…...

Wan2.2-I2V-A14B开源模型:符合ISO/IEC 23053 AI系统可解释性要求

Wan2.2-I2V-A14B开源模型&#xff1a;符合ISO/IEC 23053 AI系统可解释性要求 1. 镜像概述与核心价值 Wan2.2-I2V-A14B私有部署镜像是一款专为文生视频场景优化的AI模型运行环境。这个镜像最突出的特点是完全符合ISO/IEC 23053标准对AI系统可解释性的要求&#xff0c;让用户不…...

Fish Speech 1.5快速上手:一键部署,轻松实现中英日韩13种语言语音合成

Fish Speech 1.5快速上手&#xff1a;一键部署&#xff0c;轻松实现中英日韩13种语言语音合成 1. 为什么选择Fish Speech 1.5&#xff1f; 上周我帮一个跨国团队部署语音合成系统&#xff0c;他们需要在24小时内完成中英日韩四语的商品介绍语音生成。传统方案需要部署多个语音…...

OpenClaw学习助手:Qwen2.5-VL-7B自动解析教材插图

OpenClaw学习助手&#xff1a;Qwen2.5-VL-7B自动解析教材插图 1. 为什么需要AI学习助手 作为一名经常需要阅读大量技术文档的开发者&#xff0c;我发现自己经常陷入"读得快忘得更快"的困境。特别是遇到包含复杂图表和公式的教材时&#xff0c;手动整理关键信息要耗…...

RK3588 android12休眠唤醒后以太网不可用

现象&#xff1a;开机后连接网线可正常使用&#xff0c;系统休眠后再次唤醒后网络不通&#xff0c;等待约30秒后看门狗复位&#xff0c;gmac重新初始化后可继续使用。&#xff08;此问题还会导致屏幕唤醒点亮延时1-2秒&#xff09;日志&#xff1a;休眠唤醒后提示报错如下&…...

7 低配置设备鸿蒙运行流畅度提升技巧 | 鸿蒙开发筑基实战

7 低配置设备鸿蒙运行流畅度提升技巧 | 鸿蒙开发筑基实战 作者&#xff1a;杨建宾&#xff08;华夏之光永存&#xff09; 摘要 本文面向鸿蒙开发者&#xff0c;特别是在低配设备、低内存机型上遇到卡顿、掉帧、加载慢的工程师。提供一套通用、可落地、不求炫技的流畅度提升方…...

Vue3路由缓存优化指南:用keep-alive的include+max实现淘宝级页面保活

Vue3路由缓存优化实战&#xff1a;电商场景下的keep-alive高阶用法 电商平台的商品详情页与列表页频繁切换时&#xff0c;页面重载导致的性能损耗直接影响用户体验。去年双十一大促期间&#xff0c;某头部电商平台通过优化路由缓存策略&#xff0c;将页面切换速度提升了47%&…...

基于stm32的公司考勤系统[单片机]-计算机毕业设计源码+LW文档

摘要&#xff1a;本文设计了一款基于STM32单片机的公司考勤系统&#xff0c;详细阐述了其硬件组成和软件算法。该系统利用RFID&#xff08;或指纹识别等&#xff09;技术进行员工身份识别&#xff0c;结合实时时钟模块记录考勤时间&#xff0c;并通过OLED显示屏实时显示考勤信息…...

别再只跑Demo了!手把手教你用TensorFlow训练自己的谷物分类模型(11类数据集)

从零构建高精度谷物分类模型&#xff1a;TensorFlow实战指南 当你第一次接触深度学习时&#xff0c;可能已经运行过MNIST手写数字识别或CIFAR-10这样的标准Demo。但真正要解决实际问题时&#xff0c;这些玩具数据集远远不够。本文将带你用TensorFlow处理一个真实的11类谷物图像…...

仅限首批内测开发者获取:CPython无GIL预编译二进制+无锁标准库API速查表(含ABI兼容性矩阵与降级熔断方案)

第一章&#xff1a;Python无锁GIL环境下的并发模型概览Python 的全局解释器锁&#xff08;GIL&#xff09;长期被视为多线程 CPU 密集型任务的瓶颈。然而&#xff0c;随着 CPython 3.13 的正式引入“实验性无锁 GIL”&#xff08;--without-pymalloc 配合 --with-gildisabled 构…...

利用闲置旧电脑搭建飞牛OS家庭服务器:从DDNS配置到安全外网访问全攻略

1. 为什么选择飞牛OS搭建家庭服务器 家里有台闲置的旧电脑&#xff0c;扔了可惜&#xff0c;留着又占地方&#xff1f;其实它完全可以变身为一台高性能的家庭服务器。我去年就用一台2015年的老笔记本搭建了飞牛OS服务器&#xff0c;到现在稳定运行了300多天。飞牛OS作为国产NAS…...