hiveposeexplode 地图数据类型

问题描述 投票:0回答:1

我的数据结构如下所示:

ID       purchase_name        purchase_id
A001    {A: a}                {One: 1}
A002    {A: a, B: b}          {One: 1, Two, 2}
A003    {C: a}                {Three: 1}

这样想:{A、B、C...} 是品牌名称(即 Nike、Adidas...); {a, b, c...} 是品牌下的类别(衬衫、短裤、鞋子...); (一,二,三...}是品牌名称的内部ID,(1,2,3...)是类别名称的内部ID。现在我想将其分解为:

ID      Brand_name Brand_id Category_name Category_id
A001    A          One      a             1
A002    A          One      a             1
A002    B          Two      b             2
A003    C          Three    a             1

如果只有一个地图列要爆炸,例如buy_name,我可以使用explode 生成brand_name 列和category_name 列。但是,我尝试使用poseexplode获取位置变量,以消除为A001生成的多行,但我发现poseexplode仅适用于数组,不适用于地图数据类型。

arrays dictionary hive explode
1个回答
0
投票

首先,我假设你的

purchase_name
purchase_id
数据类型是字符串,而不是map,那么我们需要将这个问题分为三个任务:

  1. 删除不相关的字符,例如'{'、'}'和'"'

  2. 使用poseexplode将数组分解为行

  3. 用“:”分割地图

数据准备

drop table temp_table;
CREATE TABLE temp_table (
    ID STRING,
    purchase_name string,
    purchase_id string
);
INSERT INTO temp_table VALUES 
('A001', '{A: a}','{One: 1}'),
('A002', '{A: a, B: b}','{One: 1, Two: 2}'),
('A003', '{C: a}','{Three: 1}');

sql:

SELECT id
    ,split(element, ':') [0] Brand_name
    ,split(element2, ':') [0] Brand_id
    ,split(element, ':') [1] Category_name
    ,split(element2, ':') [1] Category_id
FROM (
    SELECT id
        ,pos.pos
        ,element
        ,pos2.pos2
        ,element2
    FROM temp_table LATERAL VIEW posexplode(split(replace(replace(purchase_name, '{', ''), '}', ''), ',')) pos AS pos
        ,element LATERAL VIEW posexplode(split(replace(replace(purchase_id, '{', ''), '}', ''), ',')) pos2 AS pos2
        ,element2
    ) t1
WHERE pos = pos2

输出:

id  brand_name  brand_id    category_name   category_id
A001    A   One  a   1
A002    A   One  a   1
A002    B    Two     b   2
A003    C   Three    a   1
© www.soinside.com 2019 - 2024. All rights reserved.