Hive Explode/Lateral查看多个数组

use*_*995 16 hive explode hiveql

我有一个具有以下架构的配置单元表:

COOKIE  | PRODUCT_ID | CAT_ID |    QTY    
1234123   [1,2,3]    [r,t,null]  [2,1,null]
Run Code Online (Sandbox Code Playgroud)

我如何规范化数组,以便得到以下结果

COOKIE  | PRODUCT_ID | CAT_ID |    QTY

1234123   [1]          [r]         [2]

1234123   [2]          [t]         [1] 

1234123   [3]          null       null 
Run Code Online (Sandbox Code Playgroud)

我尝试过以下方法:

select concat_ws('|',visid_high,visid_low) as cookie
,pid
,catid 
,qty
from table
lateral view explode(productid) ptable as pid
lateral view explode(catalogId) ptable2 as catid 
lateral view explode(qty) ptable3 as qty
Run Code Online (Sandbox Code Playgroud)

然而结果是笛卡尔积.

Jer*_*nks 15

您可以使用Brickhouse中的numeric_rangearray_indexUDF(http://github.com/klout/brickhouse)来解决此问题.有一篇内容丰富的博客文章详细介绍了http://brickhouseconfessions.wordpress.com/2013/03/07/exploding-multiple-arrays-at-the-same-time-with-numeric_range/

使用这些UDF,查询将是这样的

select cookie,
   array_index( product_id_arr, n ) as product_id,
   array_index( catalog_id_arr, n ) as catalog_id,
   array_index( qty_id_arr, n ) as qty
from table
lateral view numeric_range( size( product_id_arr )) n1 as n;
Run Code Online (Sandbox Code Playgroud)


小智 15

我没有使用任何UDF就找到了解决这个问题的非常好的解决方案, posexplode是一个非常好的解决方案:

SELECT COOKIE ,
ePRODUCT_ID,
eCAT_ID,
eQTY
FROM TABLE 
LATERAL VIEW posexplode(PRODUCT_ID) ePRODUCT_IDAS seqp, ePRODUCT_ID
LATERAL VIEW posexplode(CAT_ID) eCAT_ID AS seqc, eCAT_ID
LATERAL VIEW posexplode(QTY) eQTY AS seqq, eDateReported
WHERE seqp = seqc AND seqc = seqq;

  • 嘿,这行得通!需要注意的是,您的数组需要具有相同的长度,如果没有,则将它们截断为最短的长度。我也不确定它的性能,尤其是在越来越多的侧面视图中。 (3认同)

小智 10

您可以通过使用poseexplode 来实现这一点,它会提供一个0 到n 之间的整数来指示数组中每个元素在数组中的位置。然后使用这个整数 - 将其称为 pos (用于位置)以使用块表示法获取其他数组中的匹配值,如下所示:

select 
  cookie, 
  n.pos as position, 
  n.prd_id as product_id,
  cat_id[pos] as catalog_id,
  qty[pos] as qty
from table
lateral view posexplode(product_id_arr) n as pos, prd_id;
Run Code Online (Sandbox Code Playgroud)

这避免了使用导入的 UDF 以及将各种数组连接在一起(这具有更好的性能)。