浅析关于full join的问题、SQL中join时条件放在Where和On的区别

一、问题背景

1、项目背景

  我在项目中 A表5条数据,B表1条数据,在我使用 full join 时只出来5条数据,因为我只 select 了A表的字段,所以我当时还纳闷怎么没有B表的数据。我以为 full join 的表连接是 5 + 1 = 6,结果很明显不是。现在想想它就是跟 left join 那种一样,把 B 表的数据,水平连接在 A 表上。

  如果 A 表 5 条数据,B表2条数据,在用 full join 就会出来 10 条数据,是个笛卡尔积的关系。就像这样

2、注意:Oracle 支持 full join,mysql 是不支持 full join 的,但 mysql 可以使用 A union B 去实现

  刚开始我查到这个时,还以为就是我的 PG 不支持 full join,所以用的 union all,后来我一直以为 full join 是标准语法,没想到还有不支持的,就再试了下,发现 PG是支持的,进而发现了上面的问题。

3、这里还需要注意一点就是:

  join的默认方式就是outer join,所以outer可以省略

  left join:左面的那个表的记录全部返回,右面那个表只返回满足条件的的记录。不满足条件的,对应左表用null填充

  right join:和上一个正好相反

  full join:左表和右表的数据全部返回,不满足条件的用null填充

  inner join:左右两个表都同时满足的才返回

  只有一个join是inner join,left join = left outer join,right join = right outer join,full join = full outer join

二、SQL中join时条件放在Where和On的区别

1、问题

  SQL中JOIN子句是用于把来自两个或多个表的数据连接起来,在这个过程中可能会添加一些过滤条件。昨天有小伙伴问,如下图的这两种SQL写法查询结果是否会一样?(好像这是某一年阿里的面试题)

  这个问题提出来以后,多数小伙伴的回答是:查询结果应该是一样的吧,只是查询效率不一样。我当时的回答是,在Inner Join时这两种情况返回的结果是一样的,在Left、Right等情况时结果不一样

2、原因分析

  可以这么理解,当两张表在Left Join时,会生成一张连接临时表,然后再将这张连接临时表返回给用户。

(1)在On的情况下,是在生成临时表时起作用,但由于Left Join的性质,就是他不管On里面的过滤条件是否为真,都会返回左表里的记录。对于不满足条件的记录,右表字段全部是NULL。

(2)在Where的情况下,是在临时表生成好以后起作用,在对临时表进行过滤。此时,只要条件不为真的行,全部都过滤掉了。

posted @ 2017-08-13 16:06  古兰精  阅读(907)  评论(0编辑  收藏  举报