Athena Unnesting 混合类型
Athena Unnesting mixed types
我通常是这样解除嵌套的:
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 个单独的查询;一个解包单例,另一个解包数组条目 - 然后将两个结果合并在一起。
如果有人知道更有效的方法,我将不胜感激?
您应该能够通过检查对象内部是否存在特定键来实现此目的,并执行以下操作:
- 如果key不存在,这肯定是一个单一的类型对象(
map(varchar, json)
。转换成map(varchar, array(json)
。
- 如果密钥存在,请保持原样。
比方说,我们检查键 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), x -> x = 'entries')) = 1,
p,
MAP(ARRAY['entries'], array[cast(array[p] as json)])
)
它将单个对象转换为看起来像常规对象的工作map(varchar, array(json))
,这使得一切看起来都相似。
我通常是这样解除嵌套的:
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 个单独的查询;一个解包单例,另一个解包数组条目 - 然后将两个结果合并在一起。
如果有人知道更有效的方法,我将不胜感激?
您应该能够通过检查对象内部是否存在特定键来实现此目的,并执行以下操作:
- 如果key不存在,这肯定是一个单一的类型对象(
map(varchar, json)
。转换成map(varchar, array(json)
。 - 如果密钥存在,请保持原样。
比方说,我们检查键 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), x -> x = 'entries')) = 1,
p,
MAP(ARRAY['entries'], array[cast(array[p] as json)])
)
它将单个对象转换为看起来像常规对象的工作map(varchar, array(json))
,这使得一切看起来都相似。