SQL中不同类型的表连接
1、简介
在关系型数据库中,join操作是将不同的表中的数据联合在⼀起时⾮常通⽤的⼀种做法。⾸先让我们看看join是如何操作的,然后我们探索⼀下当join和where语句同时存在的时候的执⾏顺序问题,最后来谈⼀谈不同类型的join的顺序问题。
表建⽴完之后,将会看到如下三个表。
我们将通过以上三个表来演⽰join操作。这三个表都是⽤来做演⽰的,所以我并没有使⽤主键和外键。
3、表的笛卡尔乘积
⼀般情况下,我们使⽤两个表中的相关字段进⾏join操作,例如,employee表中的DeptId字段对应于Department表中的DepId字段,通过这种⽅式进⾏join。
下⾯的⼀个例⼦是不使⽤关联字段来做表的连接。这⾥TableA和TableB以笛卡尔乘积的⽅式连在了⼀起。笛卡尔乘积就是先从第⼀个表中取出⼀条记录,和第⼆章表中的每⼀条记录配合,然后再取出第⼆条记录,同样和第⼆张表的所有记录配合,直⾄第⼀张表中的所有记录都取完。所以最终的结果数量将是两张表的乘积。
4、join两张表
当我们想做两个表的连接,⽽不是像上⾯的例⼦⼀样得到⼤量的⽆⽤的结果的时候,我们就得从两张表中选取⼀个join列。我下⾯给出的例⼦是使⽤id作为join列的。我们可以通过这种⽅式使得结果只映射我们需要的那⼀部分,从⽽过滤掉了⽆⽤数据。
注意:在笛卡尔乘积表中的第⼀⾏和第五⾏满⾜了join的映射关系,从⽽被作为结果,其他的都被过滤掉了。
5、join多张表
上⾯的例⼦是join两张表,如果想join多张表,我们需要在上⾯的结果中选择⼀列,然后再在新表中选择⼀列,将这两者作为join字段,然后指定join的规则,这样我们理论上可以join任意多张表。
⾸先,Table_A和Table_B做了连接,就上上⾯的join两张表的例⼦,然后将join的结果作为⼀张表AB。再将AB与Table_C连接。
6、join类型
在两张不同的表做连接有3中join类型。
1、full join
2、inner join
3、outer join(left outer join、right outer join)
在上⾯两个例⼦中我们看到的是inner join。如果我们连接表⾃⾝就叫做self join。这个特殊类型不会混淆连接类型。
7、full join
full join和笛卡尔有些不同,笛卡尔积会获取所有可能的结果。⽽full join将匹配的结果与所有左边的表中不匹配右边的⾏和右边的表中所有不匹配左边的⾏加在⼀起,在不匹配的地⽅使⽤NULL代替。结果⾏数=匹配⾏数+左表剩余⾏数+右表剩余⾏数。
在上⾯的图⽚中,蓝⾊的⾏是两个表匹配的⾏。
第⼆⾏,左边绿⾊,右边红⾊的是不匹配的,左表中的⾏是存在的,⽽右表中的字段则被null填充。
第三⾏,左边红⾊,右边绿⾊的同样是不匹配的,右表中的⾏是存在的,⽽左表中的字段则被null填充。
8、left join
左连接(left join)保证左表中的所有⾏都有,⽽当不匹配的时候以NULL填充右表字段。
蓝⾊匹配,红⾊和绿⾊不匹配
9、right join
反过来,右连接(right join)保证右表中所有的⾏都有,⽽当不匹配的时候以NULL填充左表字段。
蓝⾊匹配,红⾊和绿⾊不匹配
10、inner join
inner join就是只列出匹配的⾏。
11、self join
表连接⾃⾝叫做self join。为了解释⼀下这个让我们看如下图中的employee表。EmployeeID是此表的主键,ReportsTo引⽤了此表的主键。我们可以想象成这样,ReportTo字段引⽤代表该雇员的上司,其上司同样也是雇员。
看如下例⼦
这⾥,有ReportTo指向的⾏是Manager,所以employee是左表,Manager是右表。
12、执⾏顺序
当连接中有where语句的时候我们需要注意连接和where的执⾏顺序问题。
1、将where语句先于join执⾏,因为执⾏完where查询的结果将会⽐较少,从⽽join操作性能会提升。
2、将where语句后与join执⾏。
以上两者将在inner join的时候返回同样的结果,但是当使⽤outer join的时候⾄少有⼀种连接操作的返回结果不同。看下⾯例⼦。
所以记住当外连接的时候尽量先执⾏join操作然后执⾏where语句。
13、连接的顺序
当你想将inner join和outer join同时使⽤的时候join的顺序也是⾮常重要的。
什么是连接的顺序?如果我像这样连接三张表【X inner Y】left Z,顺序就是先inner join再left join。
让我们回到上⾯的例⼦中,你想得到的结果是获取所有客户的名字,不管他们是否有订单。如果他们确实有⼀些订单,还要列出了客户订购的数量。
看如下的查询【先outer join再inner join】
1、在Orders和Customers中进⾏了right join。右连接能保证你获取所有Customer的信息,不管他是否有order。
2、现在上⾯的结果将和Order Details连接。但是我们需要注意的是,在右连接的结果中有两⾏roderid为null的,因为这两个customer并没有任何order,⽽在后⾯做inner join的时候,由于orderid为null,inner join将跳过这两⾏,从⽽导致这两个customer的信息被过滤掉了。
sql left join 多表连接
再让我们看看下⾯的这个查询【先inner join再outer join】
让我们分析⼀下为什么这才是我们想要的结果。
⾸先Order和Order Details表做inner join,所有匹配的结果都将被列出来,然后将此结果作为左表,Customer表作为右表,右表的所有⾏都将被列出来,不管其匹配与否(⾔外之意,那两个没有order的customer也将被列出来)。
所以,在我们同时使⽤inner join和outer join的时候⼀定要对连接的顺序做慎重考虑。
14、获取同样数据的其他办法
看如下查询
1、⾸先查询出Customers将其作为左表
2、然后将Orders表查询出来,仍然作为左表
3、然后查询出Order Details表将其作为右表与Orders表进⾏inner join。
4、最后Customers表将于第三步查询出的结果进⾏左连接。别忘了左连接将保证Customers表不丢失任何记录。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。