微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Athena Unnesting 混合类型

如何解决Athena Unnesting 混合类型

我通常会这样:

SELECT h.field1,rp.p.key1,rp.p.key2
FROM
  mytable h
  CROSS JOIN UNnesT(h.field2) rp (p)

但是,我现在正在考虑查询 AWS CloudTrail 数据。 这里我想取消嵌套的领域各不相同......

有时它是单个对象:

{"principal":{"dataLakePrincipalIdentifier":"arn:aws:iam::......

其他时候它包含一个围绕对象数组的包装对象

{"entries":[{"id":"0","principal":{"dataLakePrincipalIdentifier":"arn:aws:iam::.........

我目前能想到的解决这个问题的唯一方法是创建 2 个单独的查询一个解包单例,另一个解包数组条目 - 然后将两个结果合并在一起。

如果有人知道更有效的方法,我将不胜感激?

解决方法

您应该能够通过检查对象内部是否存在特定键来实现此目的,并执行以下操作:

  1. 如果键不存在,这肯定是一个类型为 (map(varchar,json)。将其转换为 map(varchar,array(json) 类型的对象。
  2. 如果密钥存在,请保持原样。

假设,我们检查键 entries 是否存在:

with data as (
  select CAST(json_parse(your_json_string) AS MAP(VARCHAR,json )) as p
  from mydataset.mytable
)

select cast(json_extract(j,'$.principle') as map(varchar,integer)) as record from (
     select 
     if(
       cardinality(filter(map_keys(p),x -> x = 'entries')) = 1,p,MAP(ARRAY['entries'],array[cast(array[p] as json)])
     ) as x from data2
),unnest(cast(x['entries'] as array(json))) as z(j)

请注意这部分,特别是:

if(
  cardinality(filter(map_keys(p),array[cast(array[p] as json)])
)

它的工作是将单个对象转换为普通的 map(varchar,array(json)),从而使所有内容看起来都一样。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。