AWS Athena中的查询JSON键:值对

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

我已从AWS S3中加载的客户端接收到数据集。数据包含未命名的JSON key:value对。这不是我的专业领域,因此我正在寻找一点帮助。

过去我通常使用的JSON数据的结构类似于以下内容:

{ "name":"John", "age":30, "car":null }

我从客户端收到的数据的格式如下:

{
  "answer_id": "cc006",
  "answer": {
    "101086": 1,
    "101087": 2,
    "101089": 2,
    "101090": 7,
    "101091": 5,
    "101092": 3,
    "101125": 2
  }
}

[这是调查数据,其中左侧的键是数字客户标识,而右侧的值是他们对调查问题的答复,即,客户“ 101125”以“ 2”的值回答了调查。我需要能够使用Athena查询JSON数据,以使我的结果集类似于:

enter image description here

将未嵌套的子节点与父节点交叉连接不是问题。我不知道的是如何在不指定实际键名的情况下从数组“答案”中选择所有键。同样,我也希望能够选择所有值。

是否有可能在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 }
  ]
}

EDIT 6/4/2020

我能够使用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)

EDIT 6/5/2020

从下面的Theon响应中获取其他建议,以下DDL和Query对此进行了相当大的简化。

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)
arrays json amazon-athena
1个回答
1
投票

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可以解决问题。

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