假设有两张table:
table1.c1 table1.c2
1 1 A
2 1 B
3 1 C
4 2 A
5 2 B
以及
table2.c1 table2.c2
1 2 A
2 2 D
3 3 A
4 3 B
当我这样做时:
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)
在Hive里,我得到:
t1.c1 t2.c2
1 2 A
这是预期的结果,没问题。但是,当我这么做的时候:
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)
我得到:
t1.c1 t2.c2
1 1 NULL
2 2 NULL
3 2 A
所以,filter-in-on子句似乎不像我预期的那样工作。过滤器 t1.c1 = t2.c1
以及 t1.c1 = 2
在左联接中,它在第二个表中找不到键时,没有应用 t2.c2
是 NULL
.
我想答案一定在doc中(可能在'joins occure before where子句'部分?),但我仍然不明白其中的区别。
过程是如何给出不同的结果的?
3条答案
按热度按时间9ceoxa921#
就是这样
LEFT (OUTER) JOIN
作品:您可以在
ON
-条款。如果在“right”表中找到匹配的行,它将与“left”表中的行联接。如果没有匹配的行,它仍将返回“left”行以及“right”表中的所有字段设置为null。因此,它永远不会根据ON
-条件。使用配置单元文档的术语:左表是“保留行表”,而右表是“空表”。这与
INNER JOIN
它只返回在另一个表中有匹配伙伴的行。因此不存在“保留表”,也不需要“空表”t98cgbkg2#
左连接的输出应该与完全连接的输出不同。
left join的输出将包含左表中的所有数据(在两个表中首先写入),如果右表中没有相应的数据,则显示空值。如果从查询中删除distinct并运行它,那么输出应该会消除您对左/右连接工作方式的混淆。
完全联接输出
左连接输出
gpnt7bae3#
显然,在内部连接和左连接中,配置单元对连接条件的处理方式不同。在内部联接中,可以将筛选条件放入on子句中,但在左联接中,需要将主表(本例中为t1)的筛选条件放入单独的where子句中。如果你尝试
你应该得到预期的结果。