想想我在这里问不可能的事,但把它扔在那里。 尝试在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”部分拆分为单独的行。 但所有内容都用{}包裹起来,它拒绝嵌套。
但是,尽管上述计划失败了,但仍感激收到以任何方式解决此问题的任何提示!
谢谢
答案 0 :(得分:0)
如果您的JSON数据没有易于描述的架构,则可以使用STRING
作为列的类型,然后结合使用Athena / Presto的JSON functions来查询它们并投射到MAP
和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
来确保访问第二个值不会破坏任何内容。您可能会更早地过滤掉没有冒号的值,并避免这种情况,因为您对它们不感兴趣。