MySQL 基础 ———— 连接查询

引言

本篇文章承接《数据库与SQL语句》专栏,进入DQL的重要环节,可以说,这一部分的内容应该占据SQL语言的大部分使用场景。

本篇的连接查询知识,和后面的一些重要的查询知识总结,共同构成了在工作中80%的MySQL应用场景。应该算是基础且重要的部分。

同时,我还希望能够通过更加简洁的语言总结和归纳出从需求快速定位SQL模板的口诀,比如有一个非常复杂的查询需求,那么如何通过有效的思考路径快速写出准确无误的SQL语句,也将是查询语句知识总结的重点!

一、笛卡尔积

首先,多表存储的目的是为了节省存储空间避免不必要的重复数据存储于多个表中,同时便于维护。因此往往会通过“相同字段”相互关联的方式设计数据库表,这种关联是人为定义的,并不需要MySQL来进行某种支持。

基于此,在数学中有个叫做笛卡尔积的数学概念,它指的是一个集合中的元素和另一个集合中的元素分别匹配组成不同的条目,从而构成更大的集合。

在多表查询的时候,如何完全不加任何条件,只是单纯的将两表数据进行查询,就会出现笛卡尔乘积现象,即一张表中的所有数据去逐条匹配另一张表中的所有数据,其最终结果的记录条数一定是两表的记录数的乘积。比如:

SELECT * FROM student, class 

上述SQL语句会将两个表的所有记录全部匹配。

二、连接查询的分类

SQL标准根据不同的年份,分别推出了两套标准:SQL92SQL 99

SQL92,1992年推出,它包含的连接有:

内连接(等值、非等值、自连接)

外连接(废弃)

SQL99,1999年推出,它包含的连接有:

交叉连接(笛卡尔积)

自然连接(不推荐)

内连接(等值、非等值、自连接)

外连接(最常用左外连,不常用右外连,MySQL不支持全外连)

各连接查询结果示意图,红色部分代表查询结果:

2.1 SQL92等值连接

等值连接是内连接的一种。是基于笛卡尔积实现的一种最基本的多表查询方式。如:

SELECT * FROM emp e, dept d WHERE e.`dept_id` = d.`id`;

其特点是,先通过笛卡尔积将两表相乘,然后通过筛选条件进行等值筛选

但通过等值筛选最好指定具体的查询列表,否则会将含义重复的列都查询出来,如上图中的 dept_id 和 id 都代表部门 id。查询列表的字段可以不指定表名,但效率低,另外注意,如果两表某个字段名相同,必须指定表名。形式是“表名.字段名”。

2.2 SQL92非等值连接

非等值连接也是内连接的一种。同样基于笛卡尔积。如,有 emp (左)和 salary_grade (薪水级别,右)表:

筛选薪水在 B 级别以上的员工:

SELECT e.*,s.`grade_name`,s.`salary` 标准 
FROMemp e,salary_grade s 
WHERE e.`salary` >= s.`salary` AND s.`grade_name` = 'B' ;

非等值连接用于表与表之间没有明确的对应关系,且通常会进行一个范围的筛选的情况。

2.3 SQL92自连接

自连接也是内连接的一种,其含义是表与其自身做笛卡尔积。emp 表如下:

其中 ,manager_id 代表上级领导的 emp_id ,查询员工及其上级领导的信息:

SELECT e.`emp_id` AS 员工id,e.`emp_name` AS 员工姓名,m.`emp_name` AS 上级姓名,m.`emp_id` AS 上级id,e.`salary` AS 员工薪水,e.`dept_id` AS 部门id 
FROMemp e,emp m 
WHERE e.`manager_id` = m.`emp_id` ;

自连接通常在表中的记录本身存在级联关系的情况下使用,如省市表、员工表等。

2.4 SQL92 外连接

SQL92标准的外连接目前已经基本废弃,简单了解即可,mysql无法执行这样的语句。

-- 左外连
SELECT * FROM emp e, dept d
WHERE e.`dept_id` = d.`id`(+);-- 右外连
SELECT * FROM emp e, dept d
WHERE e.`dept_id`(+) = d.`id`;

2.5 SQL99 交叉连接

交叉连接是SQL99 标准下的笛卡尔积实现,采用 CROSS JOIN 关键字:

SELECT * FROM emp e CROSS JOIN dept d;

等价于:

SELECT * FROM emp e, dept d;

同时,SQL99  的连接使用 ON 关键字进行等值筛选:

SELECT * 
FROMemp e CROSS JOIN dept d ON e.`dept_id` = d.`id` ;

2.6 SQL99 自然连接

自然连接关键字是 NATURAL JOIN ,会按照同名、同值字段,自动进行等值连接。但是限制较多,且经常需要配合 USING 关键字指定具体字段来使用,这里忽略介绍,不推荐使用。

2.7 SQL99 内连接

SQL99 对使用 INNER JOIN 来描述等值、非等值和自连接,其中 INNER 可以省略。连接条件必须使用 ON 来约束,下面以自连接进行举例,等值与非等值省略。(表结构见2.3 节),

SELECT e.`dept_id`,e.`emp_name`,m.`emp_name`,m.`emp_id`,e.`salary`,e.`dept_id` 
FROMemp e INNER JOIN emp m ON e.`manager_id` = m.`emp_id` ;

2.8 SQL99 外连接(重点)

SQL99 的外连接总共分为三类:左外连接、右外连接、全外连接。使用关键字 OUTER JOIN 连接两表,其中 OUTER 可以省略。

左外联使用 LEFT JOIN ... ON ... 来关联两表,右外联使用 RIGHT JOIN ... ON ... 来关联两表,全外联使用 FULL JOIN ... ON ...

来关联两表,但是全外联 MySQL不支持,可以通过:左外连 UNION 右外连 替代。

左外连会将 JOIN 左边的表作为主表,将右边的表中与主表有关联的数据查询出来,没有关联关系的,则不查询;右外连正好相反。来看下面的两张表,还是 emp (员工表) dept (部门表)

                  

左外连:

SELECT * 
FROMemp e LEFT JOIN dept d ON e.`dept_id` = d.`id` ;

emp 作为主表被全查了出来,并且将 dept 中相关联记录查询出,没有关联的两个部门:财务、市场部并没有被查询出来。

右外连:

SELECT * 
FROMemp e RIGHT JOIN dept d ON e.`dept_id` = d.`id` ;

dept 作为主表自然也是全部查出,就连没有员工的两个部门:财务、市场部,也一并被查询出来。

因此,我们可以看出,一般情况下,只用 LEFT JOIN ,就可以完成两种不同的效果,只需要将表的前后位置调换即可。在实际开发当中 LEFT JOIN 也是要比 RIGHT JOIN 使用频率更多。

总结

1、笛卡尔积是实现连接查询的数学模型,它代表两表相乘。

2、SQL92语法可以查询最简单的等值、非等值和自连接,三者都被称为内连接,即两表集合的交集。

3、SQL99语法全面支持了外连接,可读性更强,其中左外连接查询是学习重点。

4、SQL99 的连接查询必须通过 ON 关键字来指定连接条件,与SQL99 的连接查询不同,将连接条件从 WHERE 子句中剥离出来是SQL 99 语法的重要标志。

鸣谢:

《SQL92&SQL99实现多表查询》

《MySQL基础系列教程》

《Mysql实现全外部连接(mysql无法使用full join的解决办法)》

《MySql(十二)Sql92和Sql99的区别》

《sql92和sql99》

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

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

相关文章

MySQL 基础 ———— 子查询

引言 承接《MySQL 基础 ———— 连接查询》,本文介绍和展示SQL中子查询的使用。 子查询是出现在其他语句中的select 语句,也称为内查询。外部的查询语句,称为主查询或外查询。 一、子查询的分类和支持的子句 按照子查询出现的位置&#…

MySQL 基础 ———— SQL语句的执行顺序与 LIMIT 子句

引言 到目前为止,已经总结了常见的SQL子句,包括 SELECT 、FROM、JOIN ... ON、WHERE、GROUP BY、HAVING、ORDER BY。 虽然SQL的书写顺序是固定的,但在MySQL引擎中执行的顺序并不完全和书写顺序一致。除了上述这些子句,下面将会介…

MySQL 基础———— UNION 联合查询

引言 联合查询与连接查询不同,通过UNION 关键字,我们可以将多个查询语句一同执行并将结果集展示出来,不涉及到任何关联关系。 UNION 的含义是“联合,并集,结合”,在MySQL中可以将多个查询语句的结果合并成…

MySQL 基础————常用数据类型

引言 从第一次学习mysql开始,不知道为什么MySQL的数据类型始终没有像Java 一样深入脑海,对某些数据类型的定义和用法,也并不清晰,这篇文章,就好好总结一番,将MySQL中几个常用的数据类型归纳一下。 一、类…

MySQL 基础 ———— SAVEPOINT 的应用

引言 savepoint 关键字用于在数据库事务中设置一个存储点,在一个较长的事务中暂存数据,如果在事务末尾执行回滚,可选择性的回滚到 savepoint 设置的暂存点。 本文承接上一篇博客《MySQL 基础 ————事务与隔离级别总结》,进一…

MySQL 基础 ———— 视图的应用与总结

引言 视图是一种虚拟表,和普通表的使用是一样的,视图的一大特点就是“临时性”,是通过表动态生成的数据,只保存SQL逻辑,不保存查询结果。 视图在实际生产中主要有两种应用场景: 1、多个地方用到同样的查…

MySQL 基础 ———— 变量

一、MySQL系统变量 系统变量是由系统提供,属于服务器层面。 系统变量分为:全局变量和会话变量。 全局变量一般要加 GLOBAL 关键字,例如在《MySQL 基础 ————事务与隔离级别总结》中提到的 GLOBAL TRANSACTION,就属于全局变量…

MySQL 基础 ———— 存储过程与函数

一、存储过程介绍 存储过程是一组预先编译好的SQL语句的集合,可理解成批处理语句。它的优点主要有以下几点: 1、提高代码的重用性; 2、简化操作; 3、减少了编译次数并且减少了和数据库服务器的连接次数,提高了效率…

MySQL 基础 ———— 流程控制结构

引言 MySQL 中的流程控制作为基础知识的最后一块拼图,显得并不是特别重要,而且,在实际生产开发中,也往往不需要通过它来进行程序的控制,那么为什么还要学习它呢?我认为有以下几点: 1、知识的完…

MySQL 高级 ———— MySQL逻辑架构图简介

引言 本篇文章介绍MySQL的逻辑架构图。 MySQL并不完美,但足够灵活,能够适应高要求环境。MySQL不仅可以嵌入到应用程序中,同时也可以支持数据仓库、内容搜索、和部署软件、高可用的冗余系统、在线事务处理系统等各种应用类型。 一、MySQL逻…

Java正则表达式总结

引言 正则表达式(英文:regular expression)是用于描述字符串规则的工具,是记录文本规则的代码。 它可以用来搜索、编辑、处理文本。现有编程语言都支持正则表达式的处理,但每种语言都有细微的差别。 在Java 中&…

Linux 实操 —— Linux 系统性能分析

引言 最近配合解决压测(性能测试)方面的问题,了解到了一些可以监控 Linux 系统性能指标,如CPU、IO、内存等的工具。 此篇博客主要讲解 Linux 系统监控的一些重点内容以及 sar 命令的使用。 一、Linux 性能分析聚焦 Linux 性能…

Java 动态代理解析

引言 本博客总结自《Java 编程思想》第十四章 一、实现第一个动态代理程序 代理是软件设计中重要的设计思想,它允许我们在调用实际操作之前或之后解耦式地编写额外的操作,而一旦不需要这些操作了,就可以轻易的移除它们。 浏览了《编程思想…

MySQL 基础 ————高频函数总结

一、MySQL函数调用方式 函数调用的基本语法: SELECT 函数(实参列表) [FROM 表] 其中,对于函数,需要重点关注三点: 1、函数的名称 2、参数列表 3、函数功能 二、函数的分类 在 MySQL中,函数分为两类:1、…

MySQL 高级 —— 复合索引简介(多列索引)

引言 复合索引是指包含多个数据列的索引,与之概念相对的是单列索引,仅包含一个数据列。在大多数情况下,建立多列索引的好处都要多于单列索引。另外,复合索引最多支持16个列,但请一定不要让复合索引包含太多的列&#…

MySQL 高级 —— 索引实现的思考

引言 最近看了一个公开课,是有关MySQL对索引设计的思考。详细讲解了几种索引实现的设计思考与利弊辨析,讨论了为什么MySQL默认情况下会使用B树索引,B树索引又对B树做了哪些结构改进。 本片博客通过个人的学习理解和总结,由几种简…

Git 初学札记(十)—— Reset 回退的三种状态解析

引言 工作中经常会涉及到需要本地代码覆盖更新的操作。有时候可能是从远端git 上直接覆盖更新,或者是其他本地分支覆盖更新当前分支等等。这个时候就需要用到 reset 操作。 reset 操作分为三种类型:Soft、Mixed、Hard。今天我们就来说说这三种类型究竟…

MySQL 高级 —— 深入理解 InnoDB 与 MyISAM

引言 在文件系统中,MySQL将每个数据库(也可以称之为schema)保存为数据目录下的一个子目录。创建表时,MySQL会在数据库子目录下创建一个与表同名的.frm文件保存表的定义。因为MySQL使用文件系统的目录和文件来保存数据库和表的定义…

关于 OutOfMemoryError 的总结与解决方法

引言 本文总结自周志明的《深入理解Java虚拟机》第二章部分内容。 这部分内容,可以为后续性能调优方面的工作起到铺垫作用。 一、什么是 OutOfMemoryError OurOfMemory 简称“OOM”, 直译为“内存耗尽”或“内存溢出”,当然,并…

Windows误关闭资源管理器重启的办法

引言 有时候Windows系统在开机后,在桌面底部的任务栏中无法正常加载必要的网络连接图标或音量图标等,导致无法手动操作音量或连接网络。这时候就会需要打开“任务管理器”重新启动“资源管理器”使其重新加载这些必要的控制图标。 但是由于操作失误&am…