Join

原理如下图

注意事项

0.在Hive下,任何join都会存在着发散。所以join后使用group by进行合并!但是Spark中的join不会发散!

可以用df.dropDuplicates()来查看前后count()数量是否变化。

1.其中left/right outer join是left/right join的另一种写法

2.从join中select哪一个表的keywords字段的问题,如果自己写程序会发现其实inner join返回两个名字都叫keywords。但是实际上暗含".",因此select中必须加入'.',所以若两者完全相等,其实选哪个都一样。

3.join在指定on时就是innerjoin;不指定on时就是隐式的crossjoin笛卡尔积(a表的一行和b表中每一行都组成一行,然后逐个下去);使用cross join则显式指定笛卡尔连接。

4.技巧使用left/right join来避免笛卡尔积。

5.join中的表若有where条件,就放在on里面。

这是因为如果on和where搞混,就会有问题(如果想对右表进行限制,则一定要在on条件中进行,否则会丢失;所以对左表进行过滤必须用where,否则会冗余)

  1. 如果想对右表进行限制,则一定要在on条件中进行,若在where中进行则可能导致数据缺失,导致左表在右表中无匹配行的行在最终结果中不出现,违背了我们对left join的理解。因为对左表无右表匹配行的行而言,遍历右表后b=FALSE,所以会尝试用NULL补齐右表,但是此时我们的P2对右表行进行了限制,NULL若不满足P2(NULL一般都不会满足限制条件,除非IS NULL这种),则不会加入最终的结果中,导致结果缺失。

  2. 如果没有where条件,无论on条件对左表进行怎样的限制,左表的每一行都至少会有一行的合成结果,对左表行而言,若右表若没有对应的行,则右表遍历结束后b=FALSE,会用一行NULL来生成数据,而这个数据是多余的。所以对左表进行过滤必须用where

6.LEFT SEMI JOIN 是 IN/EXISTS 子查询的一种更高效的实现。

LEFT SEMI JOIN 的限制是, JOIN 子句中右边的表只能在ON 子句中设置过滤条件,在 WHERE 子句、SELECT 子句或其他地方过滤都不行。 注意LEFT SEMI JOIN只是为了限制而已,无法提取LEFT SEMI JOIN中的字段,因此若要提取只能用INNER JOIN搭配上ON的形式。

可以被重写为,注意此时都需要改成a.变量的名字

常用代码

References

join原理arrow-up-right

Last updated