多表查询就是将多个表通过指定的字段连接起来。当连接成功后这几张表中的数据就合成一张表,并形成了复合的结果集。基本的连接方式有五种,分别是内连接(inner)、外连接(outer)、自然连接(natural)、交叉连接(cross)和自连接。
1)内连接(inner)
内连接也叫连接,还可以称为普通连接,是最基本的一种连接。关键字是inner join,一般简写为join。连接还分为两类,等值连接与不等连接。
employees表和departments表
等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。
这两种连接的写法都是等值连接,虽然写法不同,但是查询出来的结果是一样的,查询结果中列出被连接表中的所有列,包括重复的列。可以在select后面加上distince去掉重复的列。
job_grades表
不等连接:在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、<、<=和<>。此外还有特殊的,例如between...and...和in。
这里的不等连接是通过between...and...来实现的,用salary来比较lowest_sal和highest_sal从而查询出该工资所处的等级。
2)外连接(outer)
外连接分为三种:左外连接(LEFT OUTER JOIN),右外连接(RIGHT OUTER JOIN),全外连接(FULL OUTER JOIN)。outer这个关键字可以省略不写。在左右外连接时都会以一张表为基表,而全外连接就是以全部表为基表,基表的内容会全部显示,再加上两张表的查询结果。如果基表的数据在另一张表没有匹配的数据时,就会在结果集中显示为空值。
这里用的是右外连接,即把departments表中没有关联上employees表的数据也一并显示出来。左外连接和全外连接的写法与这个类似,只是把关键字RIGHT改为LEFT或者FULL即可。
3)自然连接(natural)
自然连接会以两个表中具有相同名字的列为条件来进行等值连接,并去掉重复的属性列。如果只是列名相同而数据类型不同,则会产生错误。
为什么上面的查询结果是32条而不是106条(除去一个没有部门的员工)。其实自然连接在不加条件的情况下是会根据两个表之间所有的相同列来进行查询的,这里的employees表和departments表除了都有DEPARTMENT_ID以外还有另一个是MANAGER_ID,所以这里的自然连接是根据这两个列来进行查询匹配的。
在NATURAL JOIN子句创建等值连接时,可以使用USING子句指定等值连接中需要用到的列,可以在有多个列满足条件时进行选择使用指定的列创建等值连接。使用USING子句需要把NATURAL JOIN简写成JOIN。
4)交叉连接(cross)
交叉连接又称笛卡尔积,交叉连接不带WHERE子句,也就是没有条件。它返回的结果是被连接的两个表所有数据行的笛卡尔积,条数为第一个表的总条数乘以第二个表的总条数。关键字是cross join。
employees表中有107条数据,departments表中有27条数据。
在不加条件的情况下用cross join把employees表与departments表进行连接,得到的结果集是107×27=2889。下面代码执行的结果与上面代码的结果是一样的,也是笛卡尔积。所以在连接两个表时不加连接条件或者连接条件无效时得到的结果也是笛卡尔积。
5)自连接
自连接就是将一张表当成多张表来进行连接。employees表中的每个员工都有自己的MANAGER_ID(经理ID),并且每个经理自身又是公司的员工,自身也有经理。当我们需要将每个员工自己的名字和经理的名字都找出来时就需要用到自连接。