mysql多表查询
第11讲:MySQL的多表查询
以下文章来源于何先振,责编小何
多表查询操作的原因
表和表有很多对应的关系,比如:员工表都有自己的部门。当我们想查看一个员工的部门的时候, 就需要查询部门表。
先查员工表对应的部门id
然后通过员工的部门id,查对应的部门才能知道这个部门。如果还想知道这个部门在哪,还需要通过location_id 查对应的locations表。
这样一共就要多条sql才能查出来,后台跟数据库的网络传输就需要三次,这样就比较影响效率。
为了减少网络传输很多时候我们是可以通过多表查询写一条SQL查出来,这样后台跟数据库的网络传输只需要一次就可以搞定。
多表查询的介绍
错误的多表查询:笛卡尔积错误
员工表有107个员工
部门表有27个部门
多表连接后,一共出现2889条,此时正好等于27*107,出现了交叉连接。
出现这个交叉连接的原因,就是因为我们没有指定连接条件。
多表查询的正确方式:
需要有连接条件,通过where条件员工表的部门id关联部门表的部门id,此时查出的是106个员工。
为什么是106个员工,不是107个员工,因为之前有个员工没有部门id
如果查询的语句中出现了多个表中都存在的字段,则必须指明此字段所在的表
建议:从sql优化的角度,建议多表查询时,每个字段都指明其所在的表
可以给表起别名,在SELECT和WHERE中使用表的别名。
如果给表设置了别名,一旦在SELECT和WHERE中使用表名的话,则必须使用表的别名,而不能再使用表的原名。
如果有n个表实现多表的查询,则需要至少n-1个连接条件。
如图:三个表,两个连接条件,否则就会出现笛卡尔积错误。
多表查询的分类
角度1:等值连接 vs 非等值连接
非等值连接就是连接条件不是使用等号,非等值连接的例子:
工资等级, 不同工资等级在这个范围内的就是这个等级,比如A等级的工资范围为1000-2999
查询每个员工的工资等级 第一种使用between
查询每个员工的工资等级 第一种使用>= 或者<=
角度2:自连接 vs 非自连接
自己跟自己连接就是自连接
举例:每一个员工,都有一个上级,他的上级也是一个员工id,也就是manager_id
如果我们需要查询每个员工的上级是谁,就需要自己跟自己连接,也就是员工表的上级id和员工表的员工id连,就可以查出上级的名字。
角度3:内连接 vs 外连接
内连接:合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行。
外连接:
定义:合并具有同一列的两个以上的表的行,结果集中除了包含一个表与另一个表匹配的行之外,还查询到了左表或者右表中不匹配的行。
分类:左外连接、右外连接、满外连接
左外连接:两个表在连接过程中除了返回满足连接条件的行以外,还返回左表中不满足条件的行。
右外连接:两个表在连接过程中除了返回满足连接条件的行以外,还返回右表中不满足条件的行。
例子:查询所有员工的last_name和deptment_name。
分析:这个需要员工表与部门表进行连接,要查询所有员工必须要用外连接。
解题:
SQL92语法实现外连接:(SQL92内连接就是前面讲内连接的写法)
哪个表缺数据,就使用+ ,Mysql不支持SQL92语法中外连接的写法,Oracle支持。
SQL99语法使用 JOIN ..... ON 的方式实现多表查询。这种方式也能解决外连接的问题。MySQL是支持此种方式的。
SQL99语法如何实现内连接:
多表之间取消用逗号,使用JOIN连接,关联条件写在ON后面。也可以不省略INNER,使用INNER JOIN
employees表连接两张表
SQL99语法如何实现外连接:
左外连接:使用LEFT JOIN
右外连接:
满外连接:MySQL不支持满外连接,Oracle支持。
推荐阅读书籍