【问题标题】:Hive Explode / Lateral View multiple arraysHive Explode / 横向查看多个阵列
【发布时间】:2014-01-07 04:22:00
【问题描述】:

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

COOKIE  | PRODUCT_ID | CAT_ID |    QTY    
1234123   [1,2,3]    [r,t,null]  [2,1,null]

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

COOKIE  | PRODUCT_ID | CAT_ID |    QTY

1234123   [1]          [r]         [2]

1234123   [2]          [t]         [1] 

1234123   [3]          null       null 

我尝试了以下方法:

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

但是结果是笛卡尔积。

【问题讨论】:

    标签: hive explode hiveql


    【解决方案1】:

    如果您在 pyspark 中使用 Spark 2.4,请使用 arrays_zipposexplode

    df = (df
        .withColumn('zipped', arrays_zip('col1', 'col2'))
        .select('id', posexplode('zipped')))
    

    【讨论】:

      【解决方案2】:

      我试图解决您的方案...请尝试此代码 -

      create table info(cookie string,productid int,catid string,qty string);
      
      insert into table info
      select cookie,productid[myprod],categoryid[mycat],qty[myqty] from table
      lateral view posexplode(productid) pro as myprod,pro
      lateral view posexplode(categoryid) cate as mycat,cate
      lateral view posexplode(qty) q as myqty,q
      where myprod=mycat and mycat=myqty;
      

      注意 - 在上述陈述中,如果您放置 - select cookie,myprod,mycat,myqty from table 代替 select cookie,productid[myprod],categoryid[mycat],qty[myqty] from table 在输出中,您将获得productidcategoryidqty 数组中元素的索引。希望这会有所帮助。

      【讨论】:

        【解决方案3】:

        您可以使用posexplode 来做到这一点,它将提供一个介于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;
        

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

        【讨论】:

        • 这值得更多投票!虽然具有多个 posexplode 的替代答案可能适用于较小的表,但这是适用于较大表和大量变量(要传递给 poseexplode)的方法。
        【解决方案4】:

        我在不使用任何 UDF 的情况下找到了一个非常好的解决此问题的方法, posexplode 是一个很好的解决方案:

        选择饼干,
        ePRODUCT_ID,
        eCAT_ID,
        eQTY
        从表
        横向视图poseexplode(PRODUCT_ID) ePRODUCT_IDAS seqp, ePRODUCT_ID
        横向视图poseexplode(CAT_ID) eCAT_ID AS seqc, eCAT_ID
        横向视图poseexplode(QTY) eQTY AS seqq, eDateReported
        WHERE seqp = seqc AND seqc = seqq;

        【讨论】:

        • 嘿,这行得通!我想需要注意的是,您的数组需要具有相同的长度,如果不这样做,它会将它们截断为最短的长度。我也不确定它的性能,尤其是在横向视图越来越多的情况下。
        • 是的,因为“WHERE seqp = seqc AND seqc = seqq”,所以会取最短的,肯定会影响性能。
        【解决方案5】:

        您可以使用 Brickhouse (http://github.com/klout/brickhouse) 中的 numeric_rangearray_index UDF 来解决此问题。在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;
        

        【讨论】:

        • @Jerome .. 如果数组的大小不同,这是否可以工作.. ?
        • 我不确定不同的数组大小是否有意义。然后你必须检查 n 是否大于当前数组。就像是 。选择 cookie,IF(n >= size(array1),array_index(array1,n),null),IF(n > =size(array2),array_index(array2,n).....
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-12-24
        • 2017-07-13
        相关资源
        最近更新 更多