sql - Hive 爆炸结构键数组:值:
问题描述
这是下面的 Hive 表
CREATE EXTERNAL TABLE IF NOT EXISTS SampleTable
(
USER_ID string,
DETAIL_DATA array<struct<key:string,value:string>>
)
这就是上表中的数据——
11111 [{"key":"client_status","value":"ACTIVE"},{"key":"name","value":"Jane Doe"}]
有什么方法可以使用 HiveQL 获得以下输出?
**client_status** | **name**
-------------------+----------------
ACTIVE Jane Doe
我尝试使用explode()但我得到了这样的结果:
SELECT details
FROM sample_table
lateral view explode(DETAIL_DATA) exploded_table as details;
**details**
-------------------------------------------+
{"key":"client_status","value":"ACTIVE"}
------------------------------------------+
{"key":"name","value":"Jane Doe"}
解决方案
用于laterral view [outer] inline
获取已提取的结构元素并使用条件聚合来获取与分组在单行中的某些键相对应的值,使用 group_by user_id。
演示:
with sample_table as (--This is your data example
select '11111' USER_ID,
array(named_struct('key','client_status','value','ACTIVE'),named_struct('key','name','value','Jane Doe')) DETAIL_DATA
)
SELECT max(case when e.key='name' then e.value end) as name,
max(case when e.key='client_status' then e.value end) as status
FROM sample_table
lateral view inline(DETAIL_DATA) e as key, value
group by USER_ID
结果:
name status
------------------------
Jane Doe ACTIVE
如果你能保证数组中结构的顺序(状态总是先出现),你可以直接处理嵌套元素
SELECT detail_data[0].value as client_status,
detail_data[1].value as name
from sample_table
另一种方法,如果您不知道数组中的顺序,但数组的大小=2,则不带爆炸的 CASE 表达式将提供更好的性能:
SELECT case when DETAIL_DATA[0].key='name' then DETAIL_DATA[0].value else DETAIL_DATA[1].value end as name,
case when DETAIL_DATA[0].key='client_status' then DETAIL_DATA[0].value else DETAIL_DATA[1].value end as status
FROM sample_table
推荐阅读
- business-intelligence - 具有收入排序功能的总部位置彭博终端筛选器
- android - 如何将Web api中的数据填充到android中的自定义listView中
- php - 无法从 Facebook 登录中检索电子邮件
- c++ - 如果类使用虚拟继承,为什么对象大小会增加?
- c# - 我收到 NullReferenceException 错误,但我不知道为什么?
- c++ - C++ 环境/IDE 避免多次读取大数据集
- javascript - 动态填充复选框并动态设置其选中状态
- vagrant - Vagrant 无法在 macOS High Sierra 上的浏览器中访问服务器
- vue.js - 没有模板绑定的 VueJs 计算属性
- firebase - 一个项目有 2 个不同的 Facebook 应用程序 ID - Firebase