AWS athena 解析 JSON 数组

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

我之前曾问过一个问题,并且得到了解答(AWS Athena 将 JSON 对象数组解析为行),关于使用 Athena 解析 JSON 数组但遇到了变体。

使用示例:

SELECT user_textarray
FROM "sample"."workdetail" 
where workid = '5bb0a33f-3ca6-4f9c-9676-0b4d62dbb195'

返回结果为:

[{"userlist":"{'id': 'd87b002d-6c75-4c5a-b546-fe04cc939da9', 'name': 'John Smith'}"}, 
 {"userlist":"{'id': '41f20d65-c333-4fe5-bbe5-f9c63566cfc3', 'name': 'Larry Johnson'}"}, 
 {"userlist":"{'id': '18106aa2-e461-4ac5-b399-b2e209c0c341', 'name': 'Kim Jackson'}"}
]

我想要返回的是 id 和 name 列表,作为与原始查询中的 workid 相关的行。 我不确定为什么 JSON 是这样格式化的,而且它来自第 3 方,因此无法进行调整,因此需要弄清楚如何解析对象中的对象。

workid, id, name
5bb0a33f-3ca6-4f9c-9676-0b4d62dbb195,d87b002d-6c75-4c5a-b546-fe04cc939da9,'John Smith'
5bb0a33f-3ca6-4f9c-9676-0b4d62dbb195,41f20d65-c333-4fe5-bbe5-f9c63566cfc3,'Larry Johnson'
5bb0a33f-3ca6-4f9c-9676-0b4d62dbb195,18106aa2-e461-4ac5-b399-b2e209c0c341,'Kim Jackson'

我已经尝试过这种方法的变体,但不起作用,因此尝试确定是否需要修改“with”语句以获取对象内的对象,或者在选择时我是否需要进一步解析对象以获取我需要的元素.

with dataset as (workid, user_textarray
FROM "sample"."workdetail"
cross join unnest(user_textarray)
where workid = '5bb0a33f-3ca6-4f9c-9676-0b4d62dbb195')
select workid,
       json_extract_scalar(json, '$.userlist.name') name
from dataset
, unnest(user_textarray) as t(json);
sql amazon-athena presto trino
1个回答
0
投票

问题出在你的数据中,从 Presto/Trino 的角度来看

userlist
包含一个字符串,而不是 JSON 对象,而且这个字符串本身不是它的有效 JSON,因为它包含
'
而不是 '"'道具。

要“修复”此问题,您可以采取以下步骤(我知道的唯一解决方法):

  1. 提取
    userlist
  2. '
    替换为
    "
    (其他一些 JSON 解析器实际上会“正确”处理此问题,并且不需要此步骤,但在 Trino/Presto 的情况下不需要)
  3. 根据需要处理新的 JSON。

帮助您开始的事情:

-- sample data
with dataset(workid, user_textarray) as (
values ('5bb0a33f-3ca6-4f9c-9676-0b4d62dbb195', array['{"userlist":"{''id'': ''d87b002d-6c75-4c5a-b546-fe04cc939da9'', ''name'': ''John Smith''}"}',
 '{"userlist":"{''id'': ''41f20d65-c333-4fe5-bbe5-f9c63566cfc3'', ''name'': ''Larry Johnson''}"}',
 '{"userlist":"{''id'': ''18106aa2-e461-4ac5-b399-b2e209c0c341'', ''name'': ''Kim Jackson''}"}'
])
)

-- query
select workid,
       json_extract_scalar(replace(json_extract_scalar(json, '$.userlist'),'''', '"'), '$.name') name
from dataset,
     unnest(user_textarray) as t(json);

输出:

工作ID 名字
5bb0a33f-3ca6-4f9c-9676-0b4d62dbb195 约翰·史密斯
5bb0a33f-3ca6-4f9c-9676-0b4d62dbb195 拉里·约翰逊
5bb0a33f-3ca6-4f9c-9676-0b4d62dbb195 金杰克逊

请注意,为了您的目标,您可以使用 CTE/子查询,因此您不需要多次编写处理。

© www.soinside.com 2019 - 2024. All rights reserved.