MySQL --- 多表查询

news2024/11/25 15:42:38

多表查询、事物、以及提升查询效率最有手段的索引 

一. 多表查询

1.1 多表查询 --- 概述

1.1.1 数据准备

  • 将资料中准备好的多表查询数据准备的SQL脚本导入数据库中。

部门表:

员工表:

1.1.2 介绍

多表查询:指从多张表中查询数据,就是从多张表当中进行查询

单表查询的SQL语句:select 字段列表 from 表名;

那么要执行多表查询,只需要使用逗号分隔多张表即可,如: select 字段列表 from 表1, 表2;

查询用户表和部门表中的数据:

-- 多表查询:直接在from之后跟上多张表就可以了,多张表之间使用逗号分隔
select * from tb_depttb_emp,;

可以看到,在多表查询的结果当中,每个员工都展示了5次,将每个员工分别和五个部门进行了一次匹配, 也就是将17个员工和5个部门挨个组合了一次,就是17 * 5 = 85。

此时,我们看到查询结果中包含了大量的结果集,总共85条记录,而这其实就是员工表所有的记录(17行)与部门表所有记录(5行)的所有组合情况,这种现象称之为笛卡尔积。

笛卡尔积:笛卡尔乘积是指在数学中,两个集合(A集合和B集合它们)的所有组合情况。就相当于                      是把A集合当中的每一条记录都拿出来和B集合进行一个匹配。

                  总数据量 = A集合的数据量 * B集合的数据量

2 * 4 = 8条记录, 产生的这个结果被一个法国的数据加笛卡尔发现了,所以叫笛卡尔积。这个笛卡尔积是数学当中的一个概念,指的就是两个集合,A集合与B集合所有的组合情况。

我们知道一个员工只能归属于一个部门, 而其它无效数据我们是不需要的,所以多表查询的目的就是根据业务需求从多张表当中来查询数据,并且根据业务需要,要消除掉这些无效的笛卡尔积。

就拿当前这个例子来说,假如我们要查询的是每一个员工的信息以及员工对应的部门信息,那我们就可以将员工表当中部门ID这个字段与部门表的主键ID对应起来即可。而其它的这些数据,对于我们当前需求来说都是无效的笛卡尔积。

注意:在多表查询时,需要消除无效的笛卡尔积,只保留表关联部分的数据  

在SQL语句中,如何去除无效的笛卡尔积呢?

  • 只需要给多表查询加上连接查询的条件即可,通过连接查询的条件来消除无效的笛卡尔积。
-- 多表查询:直接在from之后跟上多张表就可以了,多张表之间使用逗号分隔
-- 在多表查询时,需要消除无效的笛卡尔积,只保留表关联部分的数据
-- 在SQL语句中,只需要给多表查询加上连接查询的条件即可去除无效的笛卡尔积
select * from tb_emp,tb_dept where tb_emp.dept_id = tb_dept.id;

在多表查询当中,消除无效的笛卡尔积之后,剩下的这一部分数据就是我们想要的正确的数据: 

由于id为17的员工,没有dept_id字段值,所以在多表查询时,根据连接查询的条件并没有查询到。

1.1.3 分类

在多表查询当中,根据查询的形式,我们将其分为两大类:一类是连接查询,一类是子查询 

多表查询可以分为:

1. 连接查询

    1. 内连接:相当于查询A表和B表,这两张表交集部分的数据

 

      2. 外连接

  • 左外连接:是以左表为基准,查询左表当中所有的数据(包括两张表交集部分的数据)

  • 右外连接:是以右表为基准,查询右表所有数据(包括两张表交集部分的数据)

2. 子查询:指的是在查询当中又嵌套了查询

1.2 内连接 

内连接查询:查询两表或多表中交集部分数据。 

 内连接从语法上可以分为:

  • 隐式内连接

  • 显式内连接

隐式内连接语法:

select  字段列表   from   表1 , 表2   where  条件 ... ;

显式内连接语法:

select  字段列表   from   表1  [ inner ]  join 表2  on  连接条件 ... ;
-- =============================内连接==============================
-- A.查询员工的姓名,及所属的部门名称(隐式内连接实现)
-- 隐式内连接:select 字段列表  from  表1,表2  where  条件...;
-- 提问:刚才所插入进来的员工表的测试数据一共有17条,为什么查询出来的结果只有16条呢?
-- 因为第17条员工的数据它是没有分配部门的,既然没有分配部门,说明这条记录它和部门表是没有关系的
-- 内连接查询的是两张表交集部分的数据,即A表当中没有和B表产生关联的数据是查询不出来的
select tb_emp.name,tb_dept.name from tb_emp,tb_dept where tb_emp.dept_id = tb_dept.id;
select tb_emp.name, tb_dept.name  -- 分别查询返回两张表中的数据
from tb_emp,tb_dept  -- 关联两张表
where tb_emp.dept_id = tb_dept.id; -- 连接查询条件消除笛卡尔积

-- 在多表查询时,如果表名较长写起来比较繁琐,可以给表起别名
select e.name as 员工姓名 , d.name as 部门名称 from tb_emp as e ,tb_dept as d where e.dept_id = d.id;

-- B.查询员工的姓名,及所属的部门名称(显示内连接实现)
-- 显式内连接:select  字段列表  from  表1  [inner]  join  表2  on  连接条件...;
select tb_emp.name,tb_dept.name from tb_emp inner join tb_dept on tb_emp.dept_id = tb_dept.id;

多表查询时给表起别名:

  • tableA as 别名1 , tableB as 别名2 ;

  • tableA 别名1 , tableB 别名2 ;

使用了别名的多表查询:

select emp.name , dept.name
from tb_emp emp inner join tb_dept dept
on emp.dept_id = dept.id;

注意事项:

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

1.3 外连接

外连接分为两种:左外连接 和 右外连接。

  • 左外连接:是以左表为基准,查询左表当中所有的数据(包括两张表交集部分的数据)

  • 右外连接:是以右表为基准,查询右表所有数据(包括两张表交集部分的数据)

左外连接语法结构:

select  字段列表   from   表1  left  [ outer ]  join 表2  on  连接条件 ... ;
  • 左外连接相当于查询表1(左表)的所有数据,当然也包含表1和表2交集部分的数据。

右外连接语法结构:

select  字段列表   from   表1  right  [ outer ]  join 表2  on  连接条件 ... ;
  •  右外连接相当于查询表2(右表)的所有数据,当然也包含表1和表2交集部分的数据。 

  • 我们把left outer join左侧的这张表也就是表1叫做左表,右侧的表2叫做右表。
  • 左外连接会完全包含左表,也就是表1当中的数据。中间outer关键字可以省略。
  • 如果是右外连接,会完全包含右表,也就是表2当中的数据。

 

 

-- =======================外连接================================
-- A.查询员工表中 所有 员工的姓名,和对应的部门名称(左外连接)
-- 注意看,要查询返回所有员工的姓名
-- 左外连接:select 字段列表 from 表1 left [outer] join 表2 on 连接条件...;
-- 由于是左外连接,因此会完全包含左表的数据,也就是tb_emp员工表的数据
select emp.name, dept.name
from tb_emp as emp
         left join tb_dept as dept on emp.dept_id = dept.id;

-- B.查询部门表中  所有  部门的名称,和对应的员工名称(右外连接)
-- 注意看,要查询返回所有部门的名称
-- 右外连接会完全包含右表的数据,即使右表当中有一部分数据和左表没有关联,也会查询出来
select emp.name as 员工姓名, dept.name as 部门名称
from tb_emp as emp
         right join tb_dept as dept on emp.dept_id = dept.id;

注意事项:

在我们项目开发当中,基本上使用的都是左外连接,右外连接使用的比较少,因为右外连接可以替换成左外连接。

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

1.4 子查询

1.4.1 介绍

子查询:指的是在查询当中又嵌套了查询。

所谓子查询指的就是在SQL语句当中嵌套select查询语句,我们把嵌套的这个select查询语句叫做嵌套查询,也称为子查询。

这条查询语句的查询条件是取决于另外一个查询语句的。

SELECT  *  FROM   t1   WHERE  column1 =  ( SELECT  column1  FROM  t2 ... );
  • 子查询外部的语句可以是insert / update / delete / select 的任何一个,最常见的是 select。

根据子查询返回的结果不同,我们将子查询分为四类,根据子查询结果的不同分为:

  1. 标量子查询:子查询返回的结果为单个值[一行一列]

  2. 列子查询:子查询返回的结果为一列,但可以是多行

  3. 行子查询:子查询返回的结果为一行,但可以是多列

  4. 表子查询:子查询返回的结果为多行多列[相当于子查询结果是一张表]

表子查询指的是子查询返回的结果为多行多列,就相当于子查询返回的结果又是一张表。

子查询可以书写的位置:

  1. where之后

  2. from之后

  3. select之后

1.4.2 标量子查询 

  • 子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询称为标量子查询。
  • 常用的操作符: = <> > >= < <=

-- ======================子查询===============================
-- 标量子查询:子查询返回的结果是一个单行单列的值
-- A.查询 "教研部" 的所有员工信息
-- 首先明确"教研部"是部门ID
-- a.查询 教研部 的部门ID --- tb_dept
select id from tb_dept where name = '教研部';  #查询结果:2
-- b.再查询该部门ID下的员工信息 --- tb_emp
select * from tb_emp where dept_id = 2;

-- 合并以上两条SQL语句,改写成一行
select * from tb_emp where dept_id = (select id from tb_dept where name = '教研部');


-- B.查询在 "方东白" 入职之后的员工信息
-- a.查询"方东白"的入职时间
select entrydate from tb_emp where name = '方东白';
-- b.再查询大于该入职时间的员工信息
select * from tb_emp where entrydate > '2012-11-01';

-- 合并以上两条SQL语句,改写成一行
select * from tb_emp where entrydate > (select entrydate from tb_emp where name = '方东白');

1.4.3 列子查询

  • 子查询返回的结果是一列(可以是多行),这种子查询称为列子查询。
  • 常用的操作符:in  、not in等

常用的操作符:

操作符描述
IN在指定的集合范围之内,多选一
NOT IN不在指定的集合范围之内
-- 列子查询:子查询返回的结果是一列多行
-- A.查询 "教研部" 和 "咨询部" 的所有员工信息
-- a.查询 "教研部" 和 "咨询部" 的部门ID --- tb_dept
-- 方式一:使用or关键字连接多个条件
select id from tb_dept where name = '教研部' or name = '咨询部'; #查询结果:3,2
-- 方式二:in关键字
select id from tb_dept where name in('教研部','咨询部');  #查询结果:3,2

-- b.根据部门ID,查询该部门下的员工信息 --- tb_emp
-- 方式一:使用or关键字连接多个条件
select * from tb_emp where dept_id = 3 or dept_id = 2;
-- 方式二:in关键字
select * from tb_emp where dept_id in (3,2);

-- 合并以上两条SQL语句,改写成一行
select * from tb_emp where dept_id in (select id from tb_dept where name in ('教研部','咨询部'));

 

 

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

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

相关文章

2023年的深度学习入门指南(13) - 写后端

2023年的深度学习入门指南(13) - 写后端 我们前面学习了用python在本机上写前端&#xff0c;也学习了使用HTML在本机写前端。同理&#xff0c;我们可以写Windows应用&#xff0c;mac应用&#xff0c;iOS应用&#xff0c;Android应用等等以适合各种终端。其实&#xff0c;最通用…

python+chrome rpc方式轻松绕过五秒盾(cloudflare)

Cloudflare 5秒盾是一种基于云技术的Web应用程序防火墙(WAF),旨在保护网站免受各种Web攻击,如SQL注入、跨站点脚本(XSS)和DDoS攻击。它能够在5秒内检测到并阻止恶意流量,并提供实时安全警报和日志记录。此外,它还提供了一系列安全功能,包括SSL / TLS加密、IP过滤、访问…

单链表你别再找我了,我怕双向链表误会

目录 带头双向循环链表的创建和初始化 创建一个新的结点&#xff08;方便复用&#xff09; 链表判空 链表打印 链表尾插 链表尾删 链表头插 链表头删 任意插入 任意删除 链表查找 链表销毁 完整代码 &#x1f60e;前言 之前我们讲了结构最简单&#xff0c;实现起来…

kettle win11 启动闪退 --启动日志

一、启动闪退 思路&#xff1a; 找原因找启动日志根据启动日志查看启动失败的原因 二、找启动日志 采用debug模式启动 查看控制台–根据控制台操作 看生成的启动日志文件 查看日志 DEBUG: Using PENTAHO_JAVA_HOME DEBUG: _PENTAHO_JAVA_HOMEE:\java8 DEBUG: _PENTAHO…

记一次靶场搭建与渗透测试

渗透目标 通过Windows7打入工作组环境&#xff0c;穿透两层内网拿到DC&#xff08;域控制器&#xff09;权限 环境搭建 环境搭建 网络拓扑 虚拟机网络配置 渗透测试 永恒之蓝外网打点 nmap -sS 192.168.2.0/24扫描外网存活主机&#xff0c;发现两台主机192.168.2.128和192…

芯片电源附近为什么放置的是0.1uF电容

日常使用情况 我们在电源滤波电路上可以看到各种各样的电容&#xff0c;100uF、10uF、100nF、10nF不同的容值&#xff0c;而在我们使用中常常会在芯片电源附近放置0.1uF电容&#xff0c;以TB67S109AFNG应用手册为例&#xff0c;其中推荐使用的也是0.1uF的电容 电容的特性 数字…

分享几款小白从零开始学习的会用到的工具/网站

大二狗接触编程也有两年了&#xff0c;差生文具多这大众都认可的一句话&#xff0c;在这里蹭一下这个活动分享一下从0开始学习编程有啥好用的工具 目录 伴侣一、Snipaste截图工具 伴侣二、Postman软件&#xff08;可用ApiPost平替&#xff09; 伴侣三、字体图标网站 伴侣四…

BlockChain-Account_TakeOver

题目描述 ECDSA 签名 假设我们的私钥为 d A d_A dA​而公钥为 Q A Q_A QA​&#xff0c; Q A d A ⋅ G Q_Ad_A\cdot G QA​dA​⋅G&#xff0c;接下来就是签名的过程&#xff0c;要签名的消息为 m m m 取 e H A S H ( m ) e HASH(m) eHASH(m)取 e e e的左边的 L n L_n L…

Baumer工业相机堡盟工业相机软件CameraExplorer常见功能使用说明二

Baumer工业相机堡盟工业相机软件CameraExplorer常见功能使用说明二 Baumer工业相机Baumer工业相机CE软件图像/视频存储功能Baumer工业相机CE软件记录日志文件功能Baumer工业相机CE软件查看图像Buffer及数据流统计信息 Baumer工业相机 Baumer工业相机堡盟相机是一种高性能、高质…

汇编五、伪指令与汇编程序结构

1、伪指令 1.1、概念 (1)伪指令是用于对汇编过程进行控制的指令&#xff0c;该类指令并不是可执行指令&#xff0c;没有对应机器码&#xff0c;只用于汇编过程中为汇编程序提供汇编信息&#xff0c;帮助编译器编译。 1.2、ASM51提供的伪指令 伪指令分为如下几类。 1.2.1、…

zuul源码分析

zuul源码解析 zuul与springboot整合的依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId></dependency>看到starter第一反应就是springboot的自动装配? 我们去…

简历制作、投递、(实习)面试技巧!!

目录 1.为什么要找实习 2.什么时候找实习 3.制作简历 4.简历注意事项 5.IT后端的校招的要求 6.简历里面写什么&#xff1f; 7.简历模板的选择 8.个人信息 9.求职意向 10.专业技能 11.项目经验 12.其他注意事项 13.找工作的手段 14.找工作的态度 ​编辑 15.面试…

IntelliJ IDEA 修改内存大小

idea有个配置文件&#xff0c;可以设置内存大小的&#xff0c;就跟咱的jvm的内存里面的堆大小&#xff0c;栈大小等等&#xff0c;可以设置的&#xff0c;而且设置了之后&#xff0c;你这个的性能就会得到提升。具体看下面怎么修改。 先说所要修改的文件 idea.vmoptions 的位置…

总结常见评价指标

整理一下在机器学习中常见的评价指标&#xff0c;包括&#xff1a; 混淆矩阵&#xff0c;TPR&#xff0c;FPR&#xff0c;TNR&#xff0c;FNR&#xff1b;Precision&#xff0c;Recall&#xff0c;Accuracy&#xff0c;F-score(F1-meature)ROC曲线&#xff0c;AUC&#xff1b; …

[Vue warn]: You may have an infinite update loop in a component render function

老板让该一个bug&#xff0c;结果一连出现好几个问题&#xff0c;然后报错也是很奇葩&#xff0c;在源代码上不能直接定位到&#xff0c;只知道在当前页面上出现的问题&#xff0c;弄了好久&#xff0c;给大家分享一下解决的经验&#xff1a; You may have an infinite update …

2023 年Windows MySql 5.7,MySql 8.0 下载安装教程, 附详细图解

文章目录 下载 MySQL 安装程序安装 MySQL 数据库安装示例数据库连接到 MySQL 服务器 在本教程中&#xff0c;我们展示如何在 Windows 平台上下载和安装 MySQL 的详细步骤。 在 Windows 平台上安装 MySQL 很简单&#xff0c;并不需要太复杂的步骤。按照本文的步骤操练起来就可以…

【Win10错误】从80190001错误码恢复

目录 一、说明 二、操作过程和错误显示 三、修复过程 四、网上的其它参考意见 一、说明 出现0x80190001错误码&#xff0c;其原因是网络认证问题引起。但不是网络断开或路由不通而引起。一般是本地身份cooki无法认证而引起&#xff0c;一般出现在登录认证过程。本篇告诉大家…

2.4G无线游戏手柄方案开发

对于游戏玩家来说&#xff0c;好的外设才能有更好的游戏体验。相比于传统的有线手柄&#xff0c;2.4G无线游戏手柄采用2.4GHz射频无线连接方式&#xff0c;摆脱了连线的困扰。相比于鼠标键盘&#xff0c;游戏手柄在大部分游戏上的使用体验都会更好&#xff0c;让你的游戏体验更…

【MATLAB第30期】基于MATLAB的adaboost多分类预测集成学习模型(四种模型GDA高斯判别分析、Knn、NB朴素贝叶斯、SVM)

【MATLAB第30期】基于MATLAB的adaboost多分类预测集成学习模型&#xff08;四种模型GDA高斯判别分析、Knn、NB朴素贝叶斯、SVM&#xff09; 一、简介 弱分类器 %1.GDA高斯判别分析 %2.Knn (NumNeighbors 5) K邻近 %3.Naive Bayes 朴素贝叶斯 %4.SVM 支持向量机 强分类器 1.a…

【Vue】生命周期

文章目录 生命周期概念一、生命周期图示二、生命周期1.beforeCreate&#xff08;&#xff09;{}2.created&#xff08;&#xff09;{}3.beforeMount&#xff08;&#xff09;{}4.mounted&#xff08;&#xff09;{}5.beforeUpdate&#xff08;&#xff09;{}6.updated&#xff…