多表查询
1.多表查询概览
由于数据表的设计特点,可能我们查询数据的时候数据来源于不同的数据表,这个时候就需要用到多表查询。首选需要明白以下概念:
(1)左连接、右连接、内连接、外连接;
(2)笛卡尔积:其实就是数学的自由组合。将表A(5条数据)和表B(6条数据)自由组合得到表C(一共有:5*6=30条数据)。
对于各种连接,有这么一张经典的图(具体的可以参考数据库左连接、右连接、内连接、全连接笔记):
补充说明:对于笛卡尔积,一般情况下由于实际的需要,笛卡尔积的出现往往不是我们需要的数据,因此一般不推荐笛卡尔积的出现和使用。本质上就是两张数据表在表间连接的时候没有给出连接条件导致的。
2.基础多表查询
(1)表间查询,举例:在HR用户靶场下,想要获取雇员的工作部门,必定需要设计多表查询:
查询方式如下(本质上是基于where查询):
(2)自表查询,通常处理方式是,采用重命名的形式将一张表改为多张表,然后使用表间查询,举例如下:
3.SQL99标准的外连接
(1)左外连接(left outer join
),比如查询雇员的部门(包括没有被分配部门的雇员):
(2)右外连接(right outer join
),查询部门中的雇员(包括那些没有雇员的部门):
(3)全外连接(full outer join
),查找部门中的雇员(即包含没有雇员的部门又包含没有部门的雇员):
说明:左外和右外连接能够通过切换表在连接时候的先后顺序改变两表的连接关系,比如在A left outer join B
,等价于 B right outer join A
。其实这种连接也可以使用原始的select来完成,只是当连接的表数量多的话不太方便了,像这种左连接其实可以改成等值连接加上左侧目标匹配字段非空+右侧目标匹配字段为空的情况。
4.Oracle自定义的外连接
Oracle中可以使用(+)
来更简洁的使用表间的连接,有(+)
的一侧不显示剩余数据,而另一侧显示剩余数据,举例如下:
注意:这个是Oracle的私有规则,并且只针对左连接和右连接,了解即可。
5.SQL99标准的交叉连接
cross join
,直接生成笛卡尔积,不推荐使用,了解即可:
6.SQL99标准的自然连接
natual join
,这个也比较好理解,就是直接寻找需要连接的两个表A和B中的相同字段,如果两个表中的字段和类型
相同,那么会使用两个表中的字段进行等值连接,如果字段相同但是类型不同
会直接报错。在我们设计数据库的时候也可以考虑将不同表中的相同字段的类型统一化,方便直接使用自然连接。使用举例如下:
但是有些时候,两个表中的可能有多个字段相同,或者多个相同字段中有某一个字段不是相同类型,,但是又想使用自然连接,我们只想要指定字段来做自然连接,这个时候Using
关键字就派上用场了。Using关键字用来指定
两个数据表在连接的时候使用的字段,如果其中某个表不含有using
中指定的字段,会直接报错,使用举例如下:
格式:A join B using(A和B中共有的字段名1,A和B中共有的字段名2...)
7.SQL99标准的内连接
说明一点,使用内连接在查询的效率上和使用原生的查询方式一样,并没有什么优势,比如,如果需要查询雇员的工作部门名和工作城市名。如果使用原生:
如果使用inner join
的话,写法如下:
8.子查询
子查询又被称为内查询或者嵌套查询。子查询的使用方式如下(查找薪水大于某指定职员的职员信息):
说明:子查询还有很多,但是比较常用的是和分组查询一起使用,具体的分组查询在下一篇文章中介绍。
9.union和intersect关键字
union
关键字用来连接两个查询的结果,需要注意的是这个union关键字其实有点像对||
运算符的一种补充,使用方式如下:举例:查询职员薪资高于15000和低于3000的职员信息:
说明:这个union在使用的时候必须保证两个union的连接对象中的字段数量、名称和属性均一致
,否则直接报错。并且union能够自己排除重复项,union all
则不会自动排除重复项。举例,将薪资大于15000和17000的连接在一起:
intersect
关键字,联想上面的union all
的重复项,这个intersect
关键字就是直接取交集,拿到这些重复项: