Hive:LEFT JOIN vs JOIN使用ON子句中的过滤器给出不同的结果

Ama*_*nda 1 hive join left-join

假设有两个表:

    table1.c1   table1.c2
1   1           A
2   1           B
3   1           C
4   2           A
5   2           B
Run Code Online (Sandbox Code Playgroud)

    table2.c1   table2.c2
1   2           A
2   2           D
3   3           A
4   3           B
Run Code Online (Sandbox Code Playgroud)

当我做:

select distinct t1.c1, t2.c2
from
schema.table1 t1
join
schema.table2 t2
on (t1.c2 = t2.c2 
    and t1.c1 = t2.c1
    and t1.c1 = 2)
Run Code Online (Sandbox Code Playgroud)

在Hive中,我得到:

    t1.c1   t2.c2
1   2   A
Run Code Online (Sandbox Code Playgroud)

这是预期的结果,没问题.但是,当我这样做时:

select distinct t1.c1, t2.c2
from
schema.table1 t1
left join
schema.table2 t2
on (t1.c2 = t2.c2 
    and t1.c1 = t2.c1
    and t1.c1 = 2)
Run Code Online (Sandbox Code Playgroud)

我明白了:

    t1.c1   t2.c2
1   1       NULL
2   2       NULL
3   2       A
Run Code Online (Sandbox Code Playgroud)

因此,ON子句中的过滤器似乎不像我预期的那样工作.该过滤器t1.c1 = t2.c1t1.c1 = 2时,在LEFT JOIN还没有得到应用,它并没有找到第二个表的键,以便t2.c2NULL.

我想答案必须是在doc(可能是在'加入条件之前发生的部分吗?')但我仍然不明白其中的区别.

如何给出不同的结果?

pie*_*t.t 6

这只是LEFT (OUTER) JOIN工作方式:

您在ON-clause中指定了一些匹配条件.如果在"右"表中找到匹配的行,则将其连接到"左"表中的行.如果没有匹配的行,它仍将返回"left"行以及"right"表中的所有字段设置为null.因此它永远不会根据条件过滤"左"表中的任何行ON.使用Hive-documentation的术语:左表是"保留的行表",而右表是"空表".

这与INNER JOIN只返回在另一个表中具有匹配伙伴的行相反.所以没有"保留表",也不需要"空表"

  • 这就是我所说的:没有与“ON”条件匹配的行,因此所有“正确”字段都设置为空。请记住,由于“ON”条件,“LEFT JOIN”永远不会从左表中过滤*任何*行。 (2认同)