测试版本为Hive
0.6.0
新浪微博 @谢纯青 回复:老bug了,0.7版本已修复, id 1534
------------------------------------------------------------------------------
左外关联(或者右外关联、全外关联)最重要的特性与原则就是主表的数据不能丢,例如有ljn001,ljn002两个表,都有a,b两个字段:
hive> select * from ljn001 order by a,b;
OK
a
b
1
1
1
2
1
3
2
3
2
4
hive> select * from ljn002 order by a,b;
OK
a
b
1
1
1
2
1
3 那么以下这个左外关联查询应该得到以下的结果:
hive> select a.*,b.*
> from ljn001
left outer join ljn002
> on (ljn001.a
= ljn002.a and ljn001.b = ljn002.b);
OK
a b a
b
1 1 1
1
1 2 1
2
1 3 1
3
2 3 NULL
NULL
2 4 NULL
NULL 但是接下来我将展示目前版本的Hive在外关联上的一个重要缺陷 :
select ljn001.*,ljn002.*
from ljn001 left outer join ljn002
on (ljn001.a = ljn002.a and ljn001.b = ljn002.b and ljn001.b =
2); 此SQL较前面的SQL多了红色标识的条件。根据外关联的原则:主表数据不能丢失,即ljn001表的数据不能丢失,当on里面的条件为真时ljn002的数据进行关联,当on里面的条件为假时ljn002的列全部为NULL。因此这个SQL的结果应该是:
a b a
b
1 1 NULL
NULL
1 2 1
2
1 3 NULL
NULL
2 3 NULL
NULL
2 4 NULL
NULL 可以在Oracle中验证此SQL的结果。 但是在Hive中结果却如下:
hive> select ljn001.*,ljn002.*
> from ljn001
left outer join ljn002
> on (ljn001.a
= ljn002.a and ljn001.b = ljn002.b and ljn001.b = 2);
OK
a b a
b
1 2 1
2 从执行计划中可以看出Hive在扫描ljn001表的map操作时就已经对b =
2进行了过滤。可见Hive把ljn001.b =
2当成了一个where筛选条件而不是一个on关联条件。因此在做Hive开发时一定要注意这个问题,否则就会产生意想不到的数据错误,也希望Hive能尽快修复这个缺陷。
|