我将事件数据存储在S3中,并希望使用雅典娜来查询数据。其中一个字段是动态JSON字段,我不知道它的字段名称。因此,我需要查询JSON中的键,然后使用这些键来查询该字段的第一个非null。下面是存储在S3中的数据的示例。
{
timestamp: 1558475434,
request_id: "83e21b28-7c12-11e9-8f9e-2a86e4085a59",
user_id: "example_user_id_1",
traits: {
this: "is",
dynamic: "json",
as: ["defined","by","the", "client"]
}
}因此,我需要一个查询来从特征列(存储为JSON)中提取键,并使用这些键来获取每个字段的第一个非空值。
我能做到的最接近的情况是使用min_by对一个值进行采样,但这不允许我在不返回空值的情况下添加where子句。我将需要使用presto的"first_value“选项,但是我不能使用从dynamic JSON字段中提取的JSON键。
SELECT DISTINCT trait, min_by(json_extract(traits, concat('$.', cast(trait AS varchar))), received_at) AS value
FROM TABLE
CROSS JOIN UNNEST(regexp_extract_all(traits,'"([^"]+)"\s*:\s*("[^"]+"|[^,{}]+)', 1)) AS t(trait)
WHERE json_extract(traits, concat('$.', cast(trait AS varchar))) IS NOT NULL OR json_size(traits, concat('$.', cast(trait AS varchar))) <> 0
GROUP BY trait发布于 2020-09-12 15:41:56
我不清楚你期望的结果是什么,以及你所说的“第一个非空值”是什么意思。在您的示例中,您同时拥有字符串值和数组值,并且它们都不为空。如果您提供更多的示例和预期的输出,将会很有帮助。
作为解决方案的第一步,这里有一种从traits中过滤掉空值的方法
如果将traits列的类型设置为map<string,string>,则应该能够执行以下操作:
SELECT
request_id,
MAP_AGG(ARRAY_AGG(trait_key), ARRAY_AGG(trait_value)) AS trait
FROM (
SELECT
request_id,
trait_key,
trait_value
FROM some_table CROSS JOIN UNNEST (trait) AS t (trait_key, trait_value)
WHERE trait_value IS NOT NULL
)但是,如果还想过滤数组中的值并挑选出第一个非空值,就会变得更加复杂。这可能可以通过组合对JSON、filter函数和COALESCE的强制转换来完成。
https://stackoverflow.com/questions/56246860
复制相似问题