【问题标题】:Athena/Presto : complex structure/arrayAthena/Presto:复杂结构/数组
【发布时间】:2019-11-25 02:36:41
【问题描述】:

认为我在这里问不可能的事情,但把它扔在那里。 试图在 Athena 中查询一些 json。 我正在处理的数据看起来像这样(摘录)

condition={
        "foranyvalue:stringlike":{"s3:prefix":["lala","hehe"]},
        "forallvalues:stringlike":{"s3:prefix":["apples","bananas"]
}

.. 我需要到这里:

...另外:键名不固定,所以有一天我可能会得到:

condition={"something not seen before":{"surprise":["haha","hoho"]}}

最后一点,我希望将其视为一个数组,并首先将“foranyvalue”和“forallvalues”部分拆分为单独的行。 但由于所有内容都包含在 {} 中,因此它拒绝取消嵌套。

但尽管上述计划失败 - 任何以任何方式解决此问题的提示都非常感激!

谢谢

【问题讨论】:

  • condition 是列名吗? JSON 是否始终采用{ "some_key:with_colon": {"some_key": ["array", "of", values"]}, "some_other_key:with_colon" ....} 形式?内部 {...} 是否总是只有 1 个条目?
  • Piotr (1)Condition是列名。 (2)"some_key_with_OR_WITHOUT_colon" (3)inner {} 总是 1 个条目 - 谢谢
  • .. 抱歉,“值数组”也可能只是一个普通的单个字符串(没有方 [] 括号)

标签: sql json presto amazon-athena unnest


【解决方案1】:

当您的 JSON 数据没有易于描述的架构时,您可以使用 STRING 作为列的类型,然后使用 Athena/Presto 的 JSON functions 来查询它们,并结合转换为 @ 987654323@ 和 UNNEST 以展平结构。

实现我认为您正在尝试做的事情的一种方法是这样的:

WITH the_table AS (
  SELECT CAST(condition AS MAP(VARCHAR, JSON)) AS condition
  FROM (
    VALUES
    (JSON '{"foranyvalue:stringlike":{"s3:prefix":["lala","hehe"]},"forallvalues:stringlike":{"s3:prefix":["apples","bananas"]}}'),
    (JSON '{"something not seen before":{"surprise":["haha","hoho"]}}')
  ) AS t (condition)
),
first_flattening AS (
  SELECT 
    SPLIT(first_level_key, ':', 2) AS first_level_key,
    CAST(first_level_value AS MAP(VARCHAR, JSON)) AS first_level_value
  FROM the_table
  CROSS JOIN UNNEST (condition) AS t (first_level_key, first_level_value)
),
second_flattening AS (
  SELECT
    first_level_key,
    second_level_key,
    second_level_value
  FROM first_flattening
  CROSS JOIN UNNEST (first_level_value) AS t (second_level_key, second_level_value)
)
SELECT
 first_level_key[1] AS "for",
 TRY(first_level_key[2]) AS condition,
 second_level_key AS "left",
 second_level_value AS "right"
FROM second_flattening

我在第一个 CTE 中包含了您作为内联 VALUES 列表提供的两个示例,以及在表声明中确切要做的事情(即要使用的列的类型)以及在查询(即演员表)取决于您的数据以及您希望/如何设置表格。 YMMV。

查询通过几个单独的步骤来展平 JSON 结构,首先展平第一级键和值,然后展平内部文档的键和值。或许可以一步完成,但分两步完成至少更易于阅读。

由于第一级键并不总是有冒号,我使用TRY 来确保访问第二个值不会破坏任何内容。您也许可以更早地过滤掉没有冒号的值并避免这种情况,因为您对它们不感兴趣。

【讨论】:

  • 您的回答拯救了我的日子。非常感谢 。请您帮忙准备以下 JSON 数据 [{"a":"12","b":"gps"},{"a":"40","b":"stat"},{"a" :"79","b":"第三方"}]
猜你喜欢
  • 2019-08-06
  • 2020-01-13
  • 2020-09-09
  • 2018-12-05
  • 2021-02-01
  • 2021-02-19
  • 2021-06-21
  • 2017-06-17
  • 1970-01-01
相关资源
最近更新 更多