如何将字符串强制转换为hiveql中的struct数组

axzmvihb  于 2021-06-27  发布在  Hive
关注(0)|答案(3)|浏览(736)

我有一个列为“periode”的配置单元表,列的类型是string。
列的值如下所示:

[{periode:20160118-20160205,nb:1},{periode:20161130-20161130,nb:1},{periode:20161130-20161221,nb:1}]
[{periode:20161212-20161217,nb:0}]

我想把这个专栏投进去 array<struct<periode:string, nb:int>> . 最终的目标是有一个原始的周期。为此,我想使用横向视图与爆炸列周期。所以我想把它改成 array<struct<string, int>> 谢谢你的帮助。西迪

mrwjdhj3

mrwjdhj31#

使用拆分函数怎么样?你应该可以做一些像

select nb, period from 
(select split(periode, "-") as periods, nb from yourtable) t
LATERAL VIEW explode(periods) sss AS period;

我没有试过,但应该有用:)
编辑:如果在模式日期之后有一个列周期,那么上面的方法应该有效。。和列nb,但看起来这里不是这样。以下查询应该适合您(详细但有效)

select period, nb from (
select 
regexp_replace(split(split(tok1,",")[1],":")[1], "[\\]|}]", "") as nb,
split(split(split(tok1,",")[0],":")[1],"-") as periods
from
(select split(YOURSTRINGCOLUMN, "},") as s1 from YOURTABLE) 
r1 LATERAL VIEW explode(s1) ss1 AS tok1
) r2 LATERAL VIEW explode(periods) ss2 AS period;
hpxqektj

hpxqektj2#

我知道这个问题是1yo,但我遇到了同样的问题,并通过使用 json_split 砖厂自定义项。

SELECT EXPLODE(
    json_split(
        '[{"periode":"20160118-20160205","nb":1},{"periode":"20161130-20161130","nb":1},{"periode":"20161130-20161221","nb":1}]'
));

col
{"periode":"20160118-20160205","nb":1}
{"periode":"20161130-20161130","nb":1}
{"periode":"20161130-20161221","nb":1}

对不起,意大利面密码。
这里还有一个类似的问题,使用json数组而不是json字符串。情况不一样,但对于任何面临这类任务的人来说,这在更大的背景下可能是有用的。

e5njpo68

e5njpo683#

你不需要“铸造”任何东西,你只需要分解数组,然后解压结构。我在你的数据中添加了一个索引,以便更清楚地说明事情的结局。
数据:

idx arr_of_structs
0   [{periode:20160118-20160205,nb:1},{periode:20161130-20161130,nb:1},{periode:20161130-20161221,nb:1}]
1   [{periode:20161212-20161217,nb:0}]

查询:

SELECT idx                          -- index
  , my_struct.periode AS periode    -- unpacks periode
  , my_struct.nb      AS nb         -- unpacks nb
FROM database.table
LATERAL VIEW EXPLODE(arr_of_structs) exptbl AS my_struct

输出:

idx     periode                 nb
0       20160118-20160205       1
0       20161130-20161130       1
0       20161130-20161221       1
1       20161212-20161217       0

你的问题有点不清楚想要的结果是什么,但是一旦你更新了它,我就会相应地修改查询。

编辑:

上面的解决方案是不正确的,我没有发现你的输入是错误的 STRING .
查询:

SELECT REGEXP_EXTRACT(tmp_arr[0], "([0-9]{8}-[0-9]{8})") AS periode
  , REGEXP_EXTRACT(tmp_arr[1], ":([0-9]*)")              AS nb
FROM (
  SELECT idx
    , pos
    , COLLECT_SET(tmp_col) AS tmp_arr
  FROM (
    SELECT idx
      , tmp_col
      , CASE WHEN PMOD(pos, 2) = 0 THEN pos+1 ELSE pos END AS pos
    FROM (
      SELECT *
        , ROW_NUMBER() OVER () AS idx
      FROM database.table ) x
    LATERAL VIEW POSEXPLODE(SPLIT(periode, ',')) exptbl AS pos, tmp_col ) y
  GROUP BY idx, pos) z

输出:

periode                 nb
20160118-20160205       1
20161130-20161130       1
20161130-20161221       1
20161212-20161217       0

相关问题