前言
前面我们梳理过了分组、排序、聚合函数等查询操作。这些都只是针对一个表的查询操作,这一节,我们要来梳理下多表查询的内容,让内容筛选的范围从单个表变成多个表。
在设计关系型数据库的时候,我们强调表与表之间的关系,还强调数据库范式。
表之间的关系可简单分为一对一、一对多、多对多三种。
表单设计的时候后要遵循三范式。
这都导致了我们要查询的信息往往不会都存在一个表单中,而是分布在多个表单中的,每个表单都可能映射着不同的实体。
例如,在学生的表单中存放着学生的基本信息,当我们需要查询学生及其成绩信息时,单独查询学生一个表就不能满足需求。因为学生和成绩信息往往是一对多的关系,且成绩信息还要管关联科目等信息。
而将这些信息都存放在学生表单中就违背了第二范式和第三范式,即产生了与学生主键不直接相关的列,且这些列存在着传递依赖。
因此分开存放就是不可毋庸置疑的操作,而查询的时候,就需要使用多表查询将其关联起来取出。
合并结果集
合并结果集的意思就是将查询到的两个结果集以增加行的形式合并到一张表中。其实说白了就是将一个表的结果集直接追加到另一个结果集之后。
这样做需要满足前提条件:列数相等,类型相同
满足了这两个条件后就可以和合并结果集了。合并结果集使用的关键字是UNION
和UNION ALL
两者的区别在于前者将去重重复的记录而后者将保留所有的记录而不会去除重复的。
书写他们的格式为:select 语句1 UNION select 语句2
其实就是字面意义上的“合并”两张表
下面有这样的两张表,其结构和数据为:
我们查询两张表的内容并分别使用UNION
和 UNION ALL
合并两个结果集来看看结果如何:
可以看到,在使用UNION 的时候,重复的id和姓名同时相同的张三被删除了而在使用UNION ALL 的时候第二个张三却没有被删除。
连接查询
同时查询多个表,只需要在FROM
关键字后面使用逗号隔开要查的多个表即可。
像这样:SELECT * FROM 表1,表2...; 限制条件
这样的查询是将多个表的列合并到一起,使得每一条记录有更多的信息。
笛卡尔积现象
以查询两个表为例,这样的查询会造成笛卡尔积的现象。笛卡尔积现象简单说就是两个表中的记录两两搭配出所有可能的组合情况。
这其实就是两个集合的笛卡尔积,我们设第一个表代表结果集为X,第二个表代表结果集为Y,用百度百科的描述来说就是:第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员
这么说可能有些抽象,那就来直接看个例子,以车和人为例,其表间关系为一对多(一个人可以对应多辆车,一辆车仅对应一个人):
有下面的表和数据;