之前一直是单表查询,但是如果一个实体的属性过多,总不能全部放在一张表中把?这样的话字段未免太多了把?这个时候就可以进行垂直分割,把一张表的内容放到两张表去存储,况且,不同的实体信息都会放在不同的表中,有些时候,我们需要结合多张表进行查询得到我们需要的信息.
下面有两张表:
第一张表cust_info,用来保存购货人的信息.有购货人id,购货人name,购货人sex,购货人age,购货人phone五个字段.
第二张表order_info,用来保存订单的信息.有作为主键的订单id,订单的所属哪个购货人的id,订单的类型order_type也就是货物的型号,订单的单个价格order_price,订单的数量order_number,也是共五个字段.
多表联结主要有三种方式,分别是内联结,外联结,自然联结三种.最常用的就是内外联结了..
内联结又称为等值联结,它基于两个表或多个表之间的相等测试,进行循环组合,最后获得满足联结条件的结果集.比如,第一个表内有4条记录,第二个表内有5条记录.若是没有设置联结条件的话,则4*5=20条组合记录全部满足条件,则返回20条记录,这个结果也叫做笛卡儿积.
example1:要求列出每个订单的详细信息(包括购货人的姓名,电话等信息).由于两个表中的cust_id字段和order_ownId字段都是标识的都是相同的实体,所以可以把这两个字段作为联结条件.tab_1 inner join tab_2 on.作为关键语句进行内联使用.
问一个感觉有点愚蠢的问题,这里为什么要使用联结呢?
因为我们要得到的结果集中存在order_info表中不存在的字段,而该字段在cust_info表中存在,所以当我们联结量表的时候,一定会得到该字段…
当然,能使用内联的地方,除了使用inner join on 来做,还可以直接使用from where来做.当然结果是一样的.
但是两者从逻辑上来讲还是不同的,在性能上也是有差异的:
外联结分为左联结,右联结以及全联结.不过mysql不支持全联结,不过我们可以通过union关键字模拟出来全联结的情况(后面会提).
左右联结.
在对表进行联结的时候,有时候会需要包含那些没有关联行的行,(通常把那些进行等值测试的字段所关联到的数据叫做关联行).外联结通过语句tab_1 left/right outer join tab_2 on进行联结.
example2:要求列出所有供货人的信息以及当前每个供货人的订单数.(包括没有订单的供货人也要列出.)
这个问题可以分为两步解决:
1.我们先查询order_info表下每个供货人的订单数量.返回的是一个结果集,这你需要知道,然后把结果集当作一个表来使用,所以我们在结果集后面加了个t2,给这个结果集取个别名叫做t2.结果集如下:
2.由于cust_info表中可以存在order_info中不存在的供货人,所以这里采用外联结进行联结.
有时候在进行多表联结的时候,根据需要可以多次联结某一张表.下面的例子表现的特别明显:
假设下面有两张表,第一张表是参赛选手的信息表.第二张表是比赛成绩信息表.
表中数据如下:
example3:要求返回把表com_res的两个数字id字段修改为id对应的name的结果集.由于这里要显示两个com_res中不存在的字段name,所以需要联结表player_info两次.这样才能出现两个name.
全联结
mysql是不支持全联结的,但是我们可以通过union关键字来模拟出全联结的情况.全联结也就是左联结+右联结的组合,只不过是把重复的记录给去除掉了.
由于要模拟全联结,是以cust_id和order_ownId为联结条件的,cust_info表中存在order_info表中不存在的cust_id,所以我们也要在order_info表中插入一条order_ownId为5的记录,这样就能看出来了.
union关键字相当于是个并集操作,比如第一个结果集为ABC三条记录,第二个结果集为BCD记录,通过union联结,默认结果集为ABCD四条记录.那是因为union默认是只显示distinct不同的记录,当然我们也可以在union之后加上all,来显示所有的记录.包括多次显示重复的记录.
由于左右联结可以相互转换,所以下面默认左表为cust_info,右表默认为order_info.
可以看到前面8条记录,可以说是两个表通过cust_id和orde_ownId联结的交集部分,而第九条记录返回的则是左联结的过程,因为左表中存在右表中不存在的联结条件;而第十条记录,也就是最后一条记录:可以看到前面的几个购货人属性字段都为null,这是因为这是进行有联结返回得到的结果,由于右表中存在左表不存在的联结条件字段,所以还是显示了出来.最后一条记录的意思可以理解为:有一个订单的购货人编号为5,但是购货人信息表中没有他的信息存在…