我正在使用hive 0.13。
我有两张桌子:
对于数据表中的每一行,我想从mymap表中获取与id和时间间隔匹配的名称。所以我想做一个像:
这样的联接select data.id, time, name from data left outer join mymap on data.id = mymap.id and time>=start_time and time<end_time
众所周知,对于数据中的每一行,mymap中都有0或1个匹配。
配置单元不支持上述查询,因为它是非等连接。将不等式条件移动到where过滤器不起作用会导致连接在应用过滤器之前爆炸:
select data.id, time, name from data left outer join mymap on data.id = mymap.id where mymap.id is null or (time>=start_time and time<end_time)
(我知道由于id匹配但没有匹配间隔的情况,查询不完全等效。这可以按照我在此处描述的那样解决:Hive: work around for non equi left join)
我该如何解决这个问题?
答案 0 :(得分:0)
您可以执行加入,然后从该表进行查询。我没有测试这段代码,但它会读取类似
的内容select id
,time
,name
from (
select d.id
,d.time
,m.name
,m.start_time
,m.end_time
from data as d LEFT OUTER JOIN mymap as m
ON d.id = m.id
) x
where time>=start_time
AND time<end_time
答案 1 :(得分:0)
您可以通过展平table2中的数据结构并使用UDF处理已连接的记录来解决此问题。
select
id,
time,
nameFinderUDF(b.name_list, time) as name
from
data a
LEFT OUTER JOIN
(
select
id,
collect_set(array(name,cast(start_time as string),cast(end_time as string))) as name_list
from
mymap
group by
id
) b
ON (a.id=b.id)
使用UDF执行类似的操作:
public String evaluate(ArrayList<ArrayList<String>> name_list,Long time) {
for (int i;i<name_list.length;i++) {
if (time >= Long.parseLong(name_list[i][1]) && time <= Long.parseLong(name_list[i][2])) {
return name_list[i][0]
return null;
}
这种方法应该使合并1到1,但它可以创建一个相当大的数据结构重复多次。它比直接连接效率更高。