问题解决:hive中的find_in_set不能用作join的条件

来源:互联网 发布:星韵抽奖软件注册码 编辑:程序博客网 时间:2024/06/05 11:08

假设有两个表A和B,其中:

表A

id

1

2

3

4

5


表B

ids

1,2,3

2,3

4,5

5,6

7,8

这里B中的ids字段是许多由逗号分隔的id。现在的任务是join两张表,条件是A.id要出现在B.ids中。

如果在mysql中,使用语句:

select * from Ajoin Bon find_in_set(A.id,B.ids) != 0;
可得结果

id      ids11,2,321,2,331,2,322,332,344,554,555,6
可以看到结果是正常的。

但是如果在hive中出入该语句,则提示错误Both left and right aliases encountered in JOIN '0' 。原因在于hive中不支持非等值连接。

————————————————————————————————————————

补充,这里的“等值连接”不是说把“!=”换成“=”就可以,事实上更改之后错误依旧。个人理解这里的“等值连接”是指做关联的两个字段一定要出现在等式的两侧,写成数学形式就是:function1(A.id) = function2(B.ids)

————————————————————————————————————————

如何解决?前提是不涉及过多编程,只用hive自带函数。

可采用如下方法:

select A.id from(select explode(split(ids,",")) as id from B) tjoin Aon t.id = A.id
先将ids按逗号分割成数组,然后行转列,这样就可以进行join了。

得到结果如下:

A.id12323455

可以看到与mysql的结果是一致的。

当然,实际工作中的寻量很复杂的,要考虑很多条件与限制。

————————————————————————————————————————

补充。比如说B中的字段是这样的 id分隔符XXX分隔符XXX。如果确认id出现的位置和长度保持不变,用substring函数截取字符串就可以。如果仅确认位置不变,可以用regexp_extract函数进行正则比配,不过速度就要比subtring慢很多了。

————————————————————————————————————————


P.S.本人在stackoverflow上提了类似的问题:https://stackoverflow.com/questions/44110635/how-to-join-tables-in-hive-using-find-in-set 不过至今没有人回答

原创粉丝点击