数据库的多表查询该如何操作?-程序员宅基地

技术标签: java  服务器  数据库MySQL  数据库  

目录

1. 多表查询的分类

1.1 角度一来讲:分为“ 等值连接” 和“非等值连接”;

1.2 角度二来讲:分为“自连接” 和 “非自连接”;

1.3 角度三来讲:分为“内连接” 和 “外连接”;

2. 等值连接与非等值连接

2.1 等值连接

2.2 非等值连接

3. 自连接与非自连接

3.1 自连接

3.2 非自连接

4. 内连接与外连接

4.1 内连接

4.2 外连接的分类

4.2.1 左外连接

4.2.2 右外连接

4.2.3 全外连接(也叫满外连接)


1. 多表查询的分类

关于数据库的多表查询,我们可以从三个方面对其进行划分,分类方式不分主次,只是它们的分类方式不同。

1.1 角度一来讲:分为“ 等值连接” 和“非等值连接”;

1.2 角度二来讲:分为“自连接” 和 “非自连接”;

1.3 角度三来讲:分为“内连接” 和 “外连接”;

2. 等值连接与非等值连接

2.1 等值连接

等值连接:见名知意,即为通过表A中的某个字段或者某些字段与表B,表C...等等中的表的一些字段进行等值判断查询。举例说明如下:

如上图为员工表 ,表名为 employees

 如上图为部门表,表名为 departments 

可以看到,两个表中有相同字段 department_id

问题一:假设我们要查询每个员工所在的部门名称,该如何查?

显然单从员工表employees中查是查不到的,但员工表中却存在每个员工所在的部门编号department_id,所以我们可以通过部门表号查询部门名称,如下图片中的查询语句:

从sql 语句中可以看到,查询条件为 employee表中的departmend_id = departmend表中的department_id,用等号进行匹配,即为等值连接。

此外有一点需要特别注意,在我写的sql语句中,对员工表起了别名为 e ,对部门表起了别名为 d,所以,在后续条件过过滤和查询时,均需要使用表的别名来替代表名,否则会出错,因为一旦你给表起了别名,那么数据库就会用你起的别名来覆盖原本的表名,这时如果你已经起了别名,却仍使用原来的表名,则数据库会报错。

如下图所示,当我给我的表起了别名但不用别名的时候,查询就会报错;错误信息显示为:列 employees_employee_id 不存在 。

所以一定要记住,一旦你给表起了别名,就需要使用表的别名,不能再使用原来的表名。

2.2 非等值连接

其实对比等值连接,非等值连接也很好理解,既然等值连接的筛选条件是通过字段相等来筛选的,那么非等值连接的筛选方式就不是通过字段相等来筛选的。

这里来说明下面这张表 job_grade 即为员工薪资水平表

现假设我们想知道各个员工的薪资水平等级是多少,该如何查询呢?

可以看到,在薪资水平表中,每个薪资水平等级都是一个范围,这里我们如果继续使用等值连接明显是无法满足我们的要求的,所以就用到了我们的非等值连接。

如下图所示:

可以看出这是我们的删选条件是使用的between...and... 通过一个范围来判断每个员工的薪资等级是多少,就可以达到我们的目的。

3. 自连接与非自连接

3.1 自连接

(1)自连接:其实自连接很好理解,举个最简单的例子,自恋,就是自己喜欢自己,同理,自连接就是自己与自己进行相连,口头表述还是不好,不如上图演示,我们还用上面的员工表。

问题如下:现假设我们要查询每个员工的上司信息,该如何查询?

思路:我们可以这样想,员工的上司,他也是员工,所以它一定也在员工表中,那么他们该怎样产生关联呢?相信各位已经想到了吧。那就是想要查询某个员工的上司的话,我们只需要让他的上司id,即manager_id = 某位员工的id, 筛选条件为 employee.manager_id = employee_id,通过这样查询,就可以得到我们想要的结果了。

那么问题又来了,同一张表,我们该怎么样实现多表查询呢?

很简单,我们只需要把一张表当成两张表就好了呀。

如下图所示:

我们可以把第一张员工表当成员工表,起别名为 e,把第二张表当成上司表,起别名为 m,此时只需要再加上我们刚才分析的删选条件,即可达到我们的目的。

3.2 非自连接

(2)非自连接:理解了自连接,非自连接就很简单明了了啊,自连接是自己与自己相连,非自连接就是自己不与自己相连,那么不与自己相连,那肯定就是和别的表进行相连了啊。

问题如下:假设我们要查询每个员工所在的部门名称,该如何查?

细心的小伙伴可能已经发现了,这个问题其实与上面从角度一来讲等值连接是同一个问题,那么在此就不用我再多说了吧,不太懂的小伙伴可以去重新看一遍上面我展示的等值连接,再细细体会体会。

4. 内连接与外连接

4.1 内连接

(1)内连接:内连接的意思就是把两个表有关联的部分都取出来,不分主表和次表;仍然拿上面员工表和部门表来举例,如果我们要查询某个员工所在的部门,就可以使用内连接来进行查询。

但此时我们需要注意,在员工表中,有的员工是没有部门的,而在部门表中,有的部门是没有员工的,如果我们使用内连接进行查询的话,没有部门的员工和没有员工的部门的相关信息,我们都是查不到的。

用图来说明,如下,内连接查询,我们把一查询到表A和表B的交集,其余剩下的数据我们都查不到,相比这样理解,大家应该更容易明白一些了吧。

那么言归正传,内连接我们应该怎么查询呢?语法又是什么呢?

这里我主要讲述SQL99语法,因为大家和企业极大多数都是用的是SQL99语法。

在SQL99语法中,给出了怎样来进行内连接查询。

内连接查询的关键字为   表A JOIN  表B  ON 查询条件

还是和上面同样的问题,假设我们要查询每个员工所在的部门名称,该如何查?

看下图语句:

这里我只是展示了取表A和表B的交集,

其实我们可以在 ON 条件之后继续 JOIN  表C ON 查询条件 ,继续取出 表B和表C 的交集,这里我就不一一展示了,有兴趣的小伙伴何以自己动手练习一下。

4.2 外连接的分类

外连接的话,它其实又分为三种

1. 左外连接

2. 右外连接

3.全外连接

这里我先解释一下,为什么会出现左外连接,右外连接这种状况。还是拿我们的员工表和部门表举例,我们知道,一个员工,它可以有归属部门,那么同样也可以没有归属部门;一个部门,它既可以有很多员工,也可以一个员工都没有,空部门。

基于这种情况的出现,就会出现左外连接右外连接以及全外连接(满外连接);我们想一想,当我们查询某个员工属于某个部门的时候,肯定要在让他在员工表中的 department_id = 部门表中的 department_id,才可以查到,那么回到刚才的问题,如果一个员工没有部门,他在数据库中的  department_id = null,还能查到他吗?如果一个部门没有员工,那么该部门下的所有 employee_id = null,还能查到吗?显然是不能的,因此就会造成左外连接右外连接的这种情况,下面会针对这些问题进行分析。

4.2.1 左外连接

先看左外连接

问题:查询各个员工所在的部门名称,并且查询出没有部门的员工信息

仍拿刚才的员工表和部门表举例,我们刚才内连接取了表A和表B的交集,那么做外连接的话,就是既要查询到表A和表B的交集(即有部门的员工的信息),又要取 员工表中没有部门的员工信息。使用图形来表示如下:

那么左外连接的sql语句又该怎么写呢?

其实很简单,我们只需要在原本内连接的sql语句上做一点改动,内连接的语法是 表A JOIN 表B  ON 条件,左外连接的语法则为  表A LEFT JOIN 表B  ON 条件,在JOIN 左侧加上左外连接关键词LEFT即可,如下图中SQL语句所示。

 

4.2.2 右外连接

右外连接:明白了左外连接,右外连接就很好理解了嘛

问题:查询各个员工所在的部门名称,并且查询出没有员工的部门信息。

用图来表示如下:

左外连接的语法各位明白了,比葫芦画瓢,右外连接的其实也很好想的对吧,

就是把 左外连接中的 LEFT 换成英文单词‘右’RIGHT就可以了。左外连接右外连接sql语句在上图已显示,这里不再重复展示。

4.2.3 全外连接(也叫满外连接)

接下来看 全外连接:左外连接和右外连接明白了之后,我们再来看全外连接,其实也就很简单了,就是取并集呗,既要员工部门相关的信息,又要没有部门员工的相关信息,还要没有员工的相关部门信息。用图片展示如下所示:

在表示如何表示全外连接之前,我先来考一考各位,上图有表A和表B两张表,那么他们一共有几种情况呢?

答案是7种,如下所示:

我们将这7种情况命名为 左上,左中,左下,右上,右中,右下,中

然后我们来看,左上其实就是对应我们的左外连接;

右上就是对应我们的右外连接;

中就是对应我们的内连接;

那么剩余的四种情况我们该如何进行演示呢?

先看左中,左中就是在坐上的前提下,不要中间相同的部分,那如果从这个角度老考虑的话,我们是不是只要在原本左外连接语句的基础上,加上一个筛选条件  where 表.字段 is null就可以了啊。

如下所示:

执行Sql语句之后,可以看到,我查询到了一条记录,employee_id 为178号的员工没有归属部门,是不是就达到了我们想要的结果了呢。

同理,如果我们想要得到右中的结果,只需要在右外连接的基础上加上一个过滤条件 where 表.字段 is null就可以了。

如下所示:

从查询结果可以看出,查到的部门均是没有员工的部门。

这个时候我们再看看全外连接,实现全外连接之前,需要先说明两个数据库关键字  UNION和UNION ALL,这两个个关键字均使用来实现全外连接的,那他们有什么不一样呢?

先看UNION,UNION就是直接对两个表取并集,会去除重复的字段;

而UNION ALL也是直接对两个表取并集,但不会去除重复的字段;

从效率上来讲,因为UNION需要去除重复字段,在数据量小的时候还好,一旦数据量较大达到百万甚至千万级别时,因为UNION会去除重复字段需要耗费大量时间,所以效率会低一些,而反观UNION ALL ,因为它不会去除重复字段,所以效率会比UNION高,这一点要记住。

因此在平常使用时以及开发过程中,推荐使用UNION ALL,少用UNION,但也要根据实际业务需求来定夺。

学会了这两个关键字之后,我们在来实现并集是不是就简单多了啊。

这个时候想要实现左下的并集,只需要将实现左上的SQL语句 UNION ALL 实现右中的SQL语句即可,或者将实现左中的SQL语句 UNION ALL 右上的SQL语句;这里我只举一个例子就是用左上和右中,右下以及剩余的情况在看懂了我举得例子之后,想必自己动手也可以完成。

SQL语句例子如下图所展示:

从表中查询结果可以看到,我们既查询到了没有部门的员工信息,也查询到了没有员工的部门信息,以及员工与部门与之对应的员工信息。到此为止,我们所有的目标都已经达到。

希望通过这篇文章,各位可以更加清晰地了解多表查询操作,写此文章也是为了巩固我自己对多表查询的理解,如哪处有错误,还望各位进行指正,让我们一起努力,成功高级架构师!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_70325779/article/details/130913733

智能推荐

python色卡识别_用Python帮小姐姐选口红,人人都是李佳琦-程序员宅基地

文章浏览阅读502次。原标题:用Python帮小姐姐选口红,人人都是李佳琦 对于李佳琦,想必知道他的女生要远远多于男生,李佳琦最早由于直播向广大的网友们推荐口红,逐渐走红网络,被大家称作“口红一哥”。不可否认的是,李佳琦的直播能力确实很强,他能够抓住绝大多数人的心理,让大家喜欢看他的直播,看他直播推荐的口红适不适合自己,色号适合什么样子的妆容。为了提升效率,让自己的家人或者女友能够快速的挑选出合适自己妆容的口红色号,今..._获取口红品牌 及色号,色值api

linux awk命令NR详解,linux awk命令详解-程序员宅基地

文章浏览阅读3.6k次。简介awk命令的名称是取自三位创始人Alfred Aho 、Peter Weinberger 和 Brian Kernighan姓名的首字母,awk有自己的程序设计语言,设计简短的程序,读入文件,数据排序,处理数据,生成报表等功能。awk 通常用于文本处理和报表生成,最基本功能是在文件或者字符串中基于指定规则浏览和抽取信息,awk抽取信息后,才能进行其他文本操作。awk 通常以文件的一行为处理单位..._linux awk nr

android 网络连接失败!failed to connect to /192.168.1.186(port 8080)_failed to connect to 192.168.88.218:80-程序员宅基地

文章浏览阅读1.3w次,点赞5次,收藏2次。在网上找了一个小时,一直没有头绪,因为上个星期还是好好的,最后看到一个大神的解答,只需要将防火墙关闭就好了.原本向测试功能的,却卡在了登录上.以此记录.另外好像还有种错误是电脑与手机连接的WiFi不同,也可以看看...._failed to connect to 192.168.88.218:80

matlab 多径衰落,利用MATLAB仿真多径衰落信道.doc-程序员宅基地

文章浏览阅读1.9k次。利用MATLAB仿真多种多径衰落信道摘要:移动信道的多径传播引起的瑞利衰落,时延扩展以及伴随接收过程的多普勒频移使接受信号受到严重的衰落,阴影效应会是接受的的信号过弱而造成通信的中断:在信道中存在噪声和干扰,也会是接收信号失真而造成误码,所以通过仿真找到衰落的原因并采取一些信号处理技术来改善信号接收质量显得很重要,这里利用MATLAB对多径衰落信道的波形做一比较。一,多径衰落信道的特点关于多径衰落..._matlab多径衰落工具箱

python对json的操作及实例解析_import json灰色-程序员宅基地

文章浏览阅读1w次,点赞2次,收藏17次。Json简介:Json,全名 JavaScript Object Notation,是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。(来自百度百科)python关于json文_import json灰色

mysql实现MHA高可用详细步骤_mysql mha超详细教程-程序员宅基地

文章浏览阅读1.1k次,点赞6次,收藏3次。一、工作原理MHA工作原理总结为以下几条:(1) 从宕机崩溃的 master 保存二进制日志事件(binlog events);(2) 识别含有最新更新的 slave ;(3) 应用差异的中继日志(relay log) 到其他 slave ;(4) 应用从 master 保存的二进制日志事件(binlog events);(5) 通过Manager控制器提升一个 slave 为新 m..._mysql mha超详细教程

随便推点

Linux环境下主从搭建心得(高手勿喷)_linux的java主从策略是什么-程序员宅基地

文章浏览阅读194次。一 java环境安装:1 安装JDK 参考链接地址:https://blog.csdn.net/qq_42815754/article/details/82968464注:有网情况下直接 yum 一键安装:yum -y list java(1)首先执行以下命令查看可安装的jdk版本(2)选择自己需要的jdk版本进行安装,比如这里安装1.8,执行以下命令:yum install -y java-1.8.0-openjdk-devel.x86_64(3)安装完之后,查看安装的jdk 版本,输入以下指令_linux的java主从策略是什么

ACM第四题_acm竞赛题 i 'm from mars-程序员宅基地

文章浏览阅读104次。定义int 类型,由while实现A,B的连续输入,输出A+B的值按Ctrl Z结束循环。#include<iostream>using namespace std;int main(){ int A,B; while(cin>>A>>B) { cout<<A+B<&_acm竞赛题 i 'm from mars

TextView.SetLinkMovementMethod后拦截所有点击事件的原因以及解决方法-程序员宅基地

文章浏览阅读5.2k次。在需要给TextView的某句话添加点击事件的时候,我们一般会使用ClickableSpan来进行富文本编辑。与此同时我们还需要配合 textView.setMovementMethod(LinkMovementMethod.getInstance());方法才能使点击处理生效。但与此同时还会有一个问题:如果我们给父布局添加一个点击事件,需要在点击非链接的时候触发(例如RectclerV..._linkmovementmethod

JAVA实现压缩解压文件_java 解压zip-程序员宅基地

文章浏览阅读1.1w次,点赞6次,收藏31次。JAVA实现压缩解压文件_java 解压zip

JDK8 新特性-Map对key和value分别排序实现_java comparingbykey-程序员宅基地

文章浏览阅读1.3w次,点赞7次,收藏21次。在Java 8 中使用Stream 例子对一个 Map 进行按照keys或者values排序.1. 快速入门 在java 8中按照此步骤对map进行排序.将 Map 转换为 Stream 对其进行排序 Collect and return a new LinkedHashMap (保持顺序)Map result = map.entrySet().stream() .sort..._java comparingbykey

GDKOI2021普及Day1总结-程序员宅基地

文章浏览阅读497次。第一次参加GDKOI,考完感觉还可以,结果发现还是不行,有一些地方细节打错,有些失分严重,总结出以下几点:1.大模拟一定要注意,细节打挂就是没分,像T1就是一道大模拟题,马上切了,后面就没想着检查以下,导致有些地方挂掉了,用民间数据一测,才85分。2.十年OI一场空,不开longlonglong longlonglong见祖宗。今天的T2本来想用暴力水点分的,结果没想到longlong→intlong long\to intlonglong→int,40→040\to040→0。3.代码实现能力太差,_gdkoi

推荐文章

热门文章

相关标签