【MySQL】:深入解析多表查询(上)

个人头像
🎥 屿小夏 : 个人主页
🔥个人专栏 : MySQL从入门到进阶
🌄 莫道桑榆晚,为霞尚满天!

文章目录

  • 📑前言
  • 一. 多表关系
    • 1.1 一对多
    • 1.2 多对多
    • 1.3 一对一
  • 二. 多表查询概述
    • 2.1 概述
    • 2.2 分类
  • 三. 内外连接
    • 3.1 内连接
    • 3.2 外连接
  • 🌤️全篇总结

📑前言

在数据库查询中,多表查询是一项重要的技能,尤其在处理复杂的业务逻辑和关联数据时尤为重要。多表查询涉及到不同表之间的关系,如一对多、多对多和一对一等,以及内连接和外连接等查询方式。本篇博客将深入探讨多表查询的相关概念、语法和实际案例,帮助读者掌握如何灵活运用多表查询来满足各种业务需求。

一. 多表关系

项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系。

基本上分为三种

  • 一对多(多对一)
  • 多对多
  • 一对一

1.1 一对多

案例: 部门 与 员工的关系

关系: 一个部门对应多个员工,一个员工对应一个部门

实现: 在多的一方建立外键,指向一的一方的主键

image-20231220143255246

1.2 多对多

案例: 学生 与 课程的关系

关系: 一个学生可以选修多门课程,一门课程也可以供多个学生选择

实现: 建立第三张中间表,中间表至少包含两个外键,分别关联两方主键

image-20231220143321970

1.3 一对一

案例: 用户 与 用户详情的关系

关系: 一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率

实现: 在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)

image-20231220143355695

二. 多表查询概述

2.1 概述

多表查询就是指从多张表中查询数据。

原来查询单表数据,执行的SQL形式为:select * from emp;

那么我们要执行多表查询,就只需要使用逗号分隔多张表即可,如: select * from emp , dept; 具体的执行结果如下:

image-20231220143929761

此时,我们看到查询结果中包含了大量的结果集,总共102条记录,而这其实就是员工表emp所有的记录(17) 与

部门表dept所有记录(6) 的所有组合情况,这种现象称之为笛卡尔积。接下来,就来简单介绍下笛卡尔积。

笛卡尔积: 笛卡尔乘积是指在数学中,两个集合A集合 和 B集合的所有组合情况。

image-20231220144034636

而在多表查询中,我们是需要消除无效的笛卡尔积的,只保留两张表关联部分的数据。

image-20231220144046683

image-20231220144057315

在SQL语句中,如何来去除无效的笛卡尔积呢? 我们可以给多表查询加上连接查询的条件即可。

select * from emp , dept where emp.dept_id = dept.id;

2.2 分类

连接查询

  • 内连接:相当于查询A、B交集部分数据
  • 外连接:
  • 左外连接:查询左表所有数据,以及两张表交集部分数据
  • 右外连接:查询右表所有数据,以及两张表交集部分数据
  • 自连接:当前表与自身的连接查询,自连接必须使用表别名

子查询

image-20231220144217548

三. 内外连接

3.1 内连接

image-20231220144303092

内连接查询的是两张表交集部分的数据。(也就是绿色部分的数据)

内连接的语法分为两种: 隐式内连接、显式内连接。先来学习一下具体的语法结构。

隐式内连接

SELECT 字段列表 FROM1 ,2 WHERE 条件 ... ;

显式内连接

SELECT 字段列表 FROM1 [ INNER ] JOIN2 ON 连接条件 ... ;

案例

A. 查询每一个员工的姓名 , 及关联的部门的名称 (隐式内连接实现)
表结构: emp , dept
连接条件: emp.dept_id = dept.id

select emp.name , dept.name from emp , dept where emp.dept_id = dept.id ;
-- 为每一张表起别名,简化SQL编写
select e.name,d.name from emp e , dept d where e.dept_id = d.id;

B. 查询每一个员工的姓名 , 及关联的部门的名称 (显式内连接实现) — INNER JOIN … ON …

表结构: emp , dept
连接条件: emp.dept_id = dept.id

select e.name, d.name from emp e inner join dept d on e.dept_id = d.id;
-- 为每一张表起别名,简化SQL编写
select e.name, d.name from emp e join dept d on e.dept_id = d.id;

表的别名:
①. tablea as 别名1 , tableb as 别名2 ;
②. tablea 别名1 , tableb 别名2

注意事项:

一旦为表起了别名,就不能再使用表名来指定对应的字段了,此时只能够使用别名来指定字段。

3.2 外连接

image-20231220144551911

外连接分为两种,分别是:左外连接 和 右外连接。具体的语法结构为:

左外连接

SELECT 字段列表 FROM1 LEFT [ OUTER ] JOIN2 ON 条件 ... ;

左外连接相当于查询表1(左表)的所有数据,当然也包含表1和表2交集部分的数据。

右外连接

SELECT 字段列表 FROM1 RIGHT [ OUTER ] JOIN2 ON 条件 ... ;

右外连接相当于查询表2(右表)的所有数据,当然也包含表1和表2交集部分的数据。

案例:
A. 查询emp表的所有数据, 和对应的部门信息
由于需求中提到,要查询emp的所有数据,所以是不能内连接查询的,需要考虑使用外连接查询。
表结构: emp, dept
连接条件: emp.dept_id = dept.id

select e.*, d.name from emp e left outer join dept d on e.dept_id = d.id;
select e.*, d.name from emp e left join dept d on e.dept_id = d.id;

B. 查询dept表的所有数据, 和对应的员工信息(右外连接)

由于需求中提到,要查询dept表的所有数据,所以是不能内连接查询的,需要考虑使用外连接查询。
表结构: emp, dept
连接条件: emp.dept_id = dept.id

select d.*, e.* from emp e right outer join dept d on e.dept_id = d.id;
select d.*, e.* from dept d left outer join emp e on e.dept_id = d.id;

注意事项
左外连接和右外连接是可以相互替换的,只需要调整在连接查询时SQL中,表结构的先后顺序就可以了。而我们在日常开发使用时,更偏向于左外连接。

🌤️全篇总结

本文详细介绍了多表查询中的一对多、多对多和一对一关系,以及内连接和外连接的概念和语法结构,并通过具体案例演示了多表查询的实际应用。通过学习本文,读者可以掌握如何使用多表查询来获取关联数据,并了解如何消除无效的笛卡尔积,从而提高数据库查询的效率和准确性。

image-20231220160021552

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

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

相关文章

基于Springboot的航班进出港管理系统(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的航班进出港管理系统(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结…

力扣---删除链表的倒数第 N 个结点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2,3,4,5], n 2 输出:[1,2,3,5]示例 2: 输入:head [1], n 1 输出:[]示例 3&#xff1a…

解决Word文档中插入MathTypeca公式编号问题(适用于本科、硕士、博士论文编写)

公式编号 这写论文过程中,我们常用到的就是根据章节号要求每写一个公式就自动编号,而不是(1)、(2)之类的。那么如下图这样的是怎么实现的呢? 1.开启Mathtype右编号 这样你才能有一个编号的格式 2.对公式进行格式化…

C++入门(以c为基础)——学习笔记2

1.引用 引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空 间。在语法层面,我们认为它和它引用的变量共用同一块内存空间。 可以取多个别名,也可以给别名取别名。 b/c/d本质都是别名&#…

C++的 stack和queue 的应用和实现【双端队列的理解和应用】

文章目录 stack的理解和应用栈的理解栈的模拟实现string实现stackvector实现stack queue的理解和应用队列的理解队列的模拟实现 双端队列原理的简单理解deque的缺陷为什么选择deque作为stack和queue的底层默认容器STL标准库中对于stack和queue的模拟实现stack的模拟实现queue的…

CSRF介绍及Python实现

CSRF 文章目录 CSRF1. CSRF是什么?2. CSRF可以做什么?3. CSRF漏洞现状4. CSRF的原理5. 举例说明6. CSRF的防御Python示例 1. CSRF是什么? CSRF(Cross-Site Request Forgery),中文名称:跨站请求…

来get属于你的达坦科技令人心动的offer吧!

我们是谁 达坦科技始终致力于打造高性能Al Cloud 基础设施平台DatenLord,积极推动AI应用的落地。DatenLord通过软硬件深度融合的方式,提供高性能存储和高性能网络。为AI 应用提供弹性、便利、经济的基础设施服务,以此满足不同行业客户对AICl…

网络规划(homework 静态路由 and Rip路由表更新)

1、写出下图路由器1和路由器3中的路由表(按直接交付、特定主机交付、特定网络交付、 默认交付的顺序放置路由项) 2、写出Ri更新后的路由表(rip路由协议) 1、将Rj广播的路由消息全部1 2、直接对照着更新Ri中的路由表

SQLite字节码引擎(十二)

返回:SQLite—系列文章目录 上一篇:SQLite的架构(十一)() 下一篇:SQLite—系列文章目录 1、 摘要 SQLite 的工作原理是将 SQL 语句转换为字节码和 然后在虚拟机中运行该字节码。本文档 …

车载电子电器架构 —— 工程EOL诊断

车载电子电器架构 —— 工程EOL诊断 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己…

Navicat工具使用

Navicat的本质: 在创立连接时提前拥有了数据库用户名和密码 双击数据库时,相当于建立了一个链接关系 点击运行时,远程执行命令,就像在xshell上操作Linux服务器一样,将图像化操作转换成SQL语句去后台执行 一、打开Navi…

CCF-CSP19<2020-06>-第1/2题

本次难度: 202006-1 线性分类器 题目:202006-1 题目分析: 给定n个点,并标记为AB两类,问给定直线是否能将其分为两个点集。 简单数学知识,点在直线上满足axbyc0,点在直线割平面所得的上下其…

云备份day02

📟作者主页:慢热的陕西人 🌴专栏链接:C云备份项目 📣欢迎各位大佬👍点赞🔥关注🚓收藏,🍉留言 主要内容介绍了第三方库jsoncpp和bundle库的使用 文章目录 云备…

android 使用ollvm混淆so

使用到的工具 ndk 21.4.7075529(android studio上下载的)cmake 3.10.2.4988404(android studio上下载的)llvm-9.0.1llvm-mingw-20230130-msvcrt-x86_64.zipPython 3.11.5 环境配置 添加cmake mingw环境变量如下图: 编译 下载…

Codeforces Round 836 (Div. 2) D. Range = √Sum

题目 思路&#xff1a; #include <bits/stdc.h> using namespace std; #define int long long #define pb push_back #define fi first #define se second #define lson p << 1 #define rson p << 1 | 1 const int maxn 1e6 5, inf 1e18, maxm 4e4 5; c…

PyQt qrc2py 使用PowerShell将qrc文件转为py文件并且将导入模块PyQt或PySide转换为qtpy模块开箱即用

前言 由于需要使用不同的qt环境&#xff08;PySide&#xff0c;PyQt&#xff09;所以写了这个脚本&#xff0c;使用找到的随便一个rcc命令去转换qrc文件&#xff0c;然后将导入模块换成qtpy这个通用库(支持pyside2-6&#xff0c;pyqt5-6)&#xff0c;老版本的是Qt.py(支持pysi…

【力扣每日一题】1026. 节点与其祖先之间的最大差值

LC 1026. 节点与其祖先之间的最大差值 题目描述 给定二叉树的根节点 root&#xff0c;找出存在于 不同 节点 A 和 B 之间的最大值 V&#xff0c;其中 V |A.val - B.val|&#xff0c;且 A 是 B 的祖先。 &#xff08;如果 A 的任何子节点之一为 B&#xff0c;或者 A 的任何子…

算法刷题Day23 | 回溯算法基础理论、 77. 组合

目录 0 引言1 回溯算法基础理论1.1 回溯算法模板1.2 2 组合2.1 我的解题2.2 剪枝操作 &#x1f64b;‍♂️ 作者&#xff1a;海码007&#x1f4dc; 专栏&#xff1a;算法专栏&#x1f4a5; 标题&#xff1a;算法刷题Day23 | 回溯算法基础理论、 77. 组合❣️ 寄语&#xff1a;书…

贪心算法|455.分发饼干

力扣题目链接 class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int index s.size() - 1; // 饼干数组的下标int result 0;for (int i g.size() - 1; i > 0;…

简约好用的TCPUDP小工具

csdn下载地址&#xff1a; https://download.csdn.net/download/a876106354/89077745