将多个数组合并到一个地图中
Posted
技术标签:
【中文标题】将多个数组合并到一个地图中【英文标题】:Merging multiple arrays into a map 【发布时间】:2020-06-02 12:52:03 【问题描述】:我有一些看起来像这样的数据(来自完整表格的样本):
| prov_id | hotel_id | m_id | apis_xml | company_id | yyyy_mm_dd |
|---------|----------|------|----------|------------|------------|
| 945 | 78888 | 3910 | [5] | 998 | 2020-05-20 |
| 1475 | 78888 | 6676 | [1,2,4] | 37 | 2020-05-20 |
| 1475 | 78888 | 6670 | [1,2,4] | 37 | 2020-05-20 |
| 945 | 78888 | 2617 | [5] | 998 | 2020-05-20 |
我想找到每家酒店的 最低 apis_xml 值,并将关联的 prov_id 设置为“primary_prov”。我可以通过在获取第一行之前对数组进行升序合并和排序来做到这一点。我对此有疑问:
SELECT
yyyy_mm_dd,
hotel_id,
prov_id as primary_prov
FROM(
SELECT
yyyy_mm_dd,
hotel_id,
prov_id,
apis_xml,
ROW_NUMBER() OVER(PARTITION BY yyyy_mm_dd, hotel_id ORDER BY apis_xml) rn
FROM(
SELECT
t.yyyy_mm_dd,
t.hotel_id,
t.prov_id,
t.apis_xml,
CAST(e.apis_xml AS INT) AS api
FROM
my_table t
LATERAL VIEW EXPLODE(apis_xml) e AS apis_xml
)s
)s
WHERE rn=1
上述查询用于获取映射到最低 apis_xml 值的 primary_prov。但是,我想要一个额外的列,其中包含额外的 xml 值以供参考。也许地图不是这里最好的用例,但它就是我想到的。键是 prov_id 而值是 apis_xml 值。输出看起来像这样,因为我需要将其保留为每个 hotel_id 一行:
| hotel_id | primary_prov | detailed_prov | yyyy_mm_dd |
|----------|--------------|--------------------------|------------|
| 78888 | 1475 | 1475: [1,2,4], 945: [5] | 2020-05-20 |
【问题讨论】:
detailed_prov
的数据类型是什么?
@GordonLinoff 我觉得地图可能最适合存储这种类型的数据,但我对其他解决方案持开放态度。在我的输出示例中,detailed_prov 将是带有 您可以使用砖房 CollectUDAF 构建map
。阅读instructions how to build JAR,添加jar,创建函数并使用:
add jar /path/to/jar/brickhouse-0.7.1.jar;
create temporary function collect as 'brickhouse.udf.collect.CollectUDAF';
SELECT yyyy_mm_dd,
hotel_id,
primary_prov,
collect(prov_id, prov_id_api ) as detailed_prov
FROM
(
SELECT
yyyy_mm_dd,
hotel_id,
max(case when rn=1 then prov_id else null end) over(partition by yyyy_mm_dd, hotel_id) as primary_prov,
collect_set(api) over (partition by yyyy_mm_dd, hotel_id, prov_id) prov_id_api, --re-assemple array to include all elements from multiple initial arrays if there are different arrays per prov_id
prov_id
FROM(
SELECT
yyyy_mm_dd,
hotel_id,
prov_id,
apis_xml,
api,
ROW_NUMBER() OVER(PARTITION BY yyyy_mm_dd, hotel_id ORDER BY api) rn
FROM(
SELECT
t.yyyy_mm_dd,
t.hotel_id,
t.prov_id,
t.apis_xml,
CAST(e.apis_xml_element AS INT) AS api
FROM
my_table t
LATERAL VIEW EXPLODE(apis_xml) e AS apis_xml_element
)s
)s
)s
group by yyyy_mm_dd,
hotel_id,
primary_prov
【讨论】:
这很好用,谢谢!创建表时,我应该设置什么类型的 'detailed_prov' 以便稍后插入工作?我想避免类型不匹配。 什么是输出?我自己没有测试。如果它真的产生 map以上是关于将多个数组合并到一个地图中的主要内容,如果未能解决你的问题,请参考以下文章