【问题标题】:How can I merge 2 partially overlapping strings using Apache Hive?如何使用 Apache Hive 合并 2 个部分重叠的字符串?
【发布时间】:2019-02-07 19:43:36
【问题描述】:

我有一个字段,其中包含一个固定长度的 id 的简短列表。 例如aab:aac:ada:afg

该字段旨在容纳最多 5 个 id,逐渐增长。我通过从可能与我现有集合部分重叠的类似构造字段添加来更新它,例如ada:afg:fda:kfc.

当连接到“更新”表时,该字段会扩展,如下例所示。 这里,id_list 是我想要“合并”的上述列表,而 table_update 是我想要“合并”到 table1 中的具有新值的表。

insert overwrite table table1
select 
  id,
  field1,
  field2,
  case
    when (some condition) then a.id_list
    else merge(a.id_list, b.id_list)
  end as id_list

from table1 a
left join
table_update b
on a.id = b.id;

我想生成一个具有以下值的组合字段: aab:aac:ada:afg:fda.

挑战在于,在执行之前我不知道字符串是否重叠或重叠多少,而且我无法运行任何外部代码或创建 UDF。

有什么建议可以解决这个问题吗?

【问题讨论】:

    标签: sql hive hiveql


    【解决方案1】:

    拆分得到数组,explode 它们,选择现有的union all 新的,使用collect_set 聚合,它将产生唯一的数组,使用concat_ws() 将数组连接成字符串。未测试:

    select concat_ws(':',collect_set(id)) 
    from
    (
    select explode(split('aab:aac:ada:afg',':')) as id  --existing
    union all 
    select explode(split('ada:afg:fda:kfc',':')) as id  --new
    );
    

    您可以使用UNION 而不是UNION ALL 在聚合到数组之前获取不同的值。或者您可以将新的和现有的字符串连接成一个,然后执行相同的操作:

    select concat_ws(':',collect_set(id)) 
    from
    (
    select explode(split(concat('aab:aac:ada:afg',':','ada:afg:fda:kfc'),':')) as id  --existing+new
    );
    

    您很可能需要在实际查询中使用lateral viewexplode。请参阅this关于横向视图使用的回答

    更新:

    insert overwrite table table1
    
    select  concat_ws(':',collect_set(a.idl)) as id_list,
           id,
           field1,
           field2
    from
    (
    select 
      id,
      field1,
      field2,
      split(
      case
        when (some condition) then a.id_list
        when b.id_list is null then a.id_list
        else concat(a.id_list,':',b.id_list)
      end,':') as id_list_array 
    
    from table1 a
         left join table_update b on a.id = b.id
    )s
    
    LATERAL VIEW OUTER explode(id_list_array ) a AS idl
    group by 
           id,
           field1,
           field2
    ;
    

    【讨论】:

    • 啊!好的,这是一个开始,但我需要对问题进行澄清:这些字段位于两个表中,我想为每一行组合它们,而不是两个单个字符串。
    • @Jono 你可以将新的和现有的字符串连接成一个,然后做同样的事情
    • 酷!我会看看我是否可以实现这个并回到这里。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-30
    • 2019-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-10
    • 2011-04-10
    相关资源
    最近更新 更多