我从客户端收到了一个加载到 AWS S3 中的数据集。数据包含未命名的 JSON 键:值对。这不是我的专业领域,所以我正在寻求一些帮助。
我过去通常使用的 JSON 数据结构与此类似:
{ "姓名":"约翰", "年龄":30, "汽车":null }
我从客户那里收到的数据的格式如下:
{
"answer_id": "cc006",
"answer": {
"101086": 1,
"101087": 2,
"101089": 2,
"101090": 7,
"101091": 5,
"101092": 3,
"101125": 2
}
}
这是调查数据,其中左侧的键是数字客户标识符,右侧的值是他们对调查问题的回答,即客户“101125”以“2”的值回答了调查。我需要能够使用 Athena 查询 JSON 数据,以便我的结果集看起来类似于:
将未嵌套的子节点与父节点交叉连接不是问题。我不知道如何在不指定实际键名的情况下从数组“answer”中选择所有键。同样,我也希望能够选择所有值。
是否可以在 Athena 中创建一个允许这些结果的虚拟表,或者我是否需要将 JSON 转换为看起来更类似于以下内容的格式:
{
"answer_id": "cc006",
"answer": [
{ "key": "101086", "value": 1 },
{ "key": "101087", "value": 2 },
{ "key": "101089", "value": 2 },
{ "key": "101090", "value": 7 },
{ "key": "101091", "value": 5 },
{ "key": "101092", "value": 3 },
{ "key": "101125", "value": 2 }
]
}
编辑 2020 年 6 月 4 日
我能够使用 Theon 下面提供的代码以及以下表结构:
CREATE EXTERNAL TABLE answer_example (
answer_id string,
answer string
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://mybucket/'
这使我能够使用以下查询来生成我需要的结果。
WITH Data AS(
SELECT
answer_id,
CAST(json_extract(answer, '$') AS MAP(VARCHAR, VARCHAR)) as answer
FROM
answer_example
)
SELECT
answer_id,
key,
element_at(answer, key) AS value
FROM
Data
CROSS JOIN UNNEST (map_keys(answer)) AS answer (key)
编辑 2020 年 6 月 5 日
根据下面 Theon 的回复中的其他建议,以下 DDL 和查询大大简化了这一过程。
DDL:
CREATE EXTERNAL TABLE answer_example (
answer_id string,
answer map<string,string>
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
LOCATION 's3://mybucket/'
查询:
SELECT
answer_id,
key,
element_at(answer, key) AS value
FROM
answer_example
CROSS JOIN UNNEST (map_keys(answer)) AS answer (key)
最佳答案
与 answer
属性的键交叉连接,然后选择相应的值。像这样的事情:
WITH data AS (
SELECT
'cc006' AS answer_id,
MAP(
ARRAY['101086', '101087', '101089', '101090', '101091', '101092', '101125'],
ARRAY[1, 2, 2, 7, 5, 3, 2]
) AS answers
)
SELECT
answer_id,
key,
element_at(answers, key) AS value
FROM data
CROSS JOIN UNNEST (map_keys(answers)) AS answer (key)
您可能可以使用 transform_keys
来创建键值对行,但上面的 SQL 可以解决这个问题。
关于arrays - 查询 JSON key :Value Pairs in AWS Athena,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62156122/