给出雅典娜的一个原始表,它类似于下面这个人为设计的示例:

Original Table:

a b cmsmessage c
... ... {"asset": {"metadata": {"item": [{"key": "author", "value": "Rob"}, { "key": "id", "value": "123"}, {"key": "version", "value": "1"}]}}} ...
... ... {"asset": {"metadata": {"item": [{ "key": "id", "value": "456"}, {"key": "author", "value": "John"}, {"key": "version", "value": "3"}]}}} ...
... ... {"asset": {"metadata": {"item": [{"key": "version", "value": "2"}, {"key": "author", "value": "Sally"}, {"key": "id", "value": "789" }]}}} ...

我试图从cmsmessage列中的字符串化JSON创建一个视图:

Desired Resultant View:

id author version
123 Rob 1
456 John 3
789 Sally 3

正如您在"Desired Resultant View"中看到的,我实际上希望根据key的值从item数组的每个对象中提取数据.

[{"key": "author", "value": "Rob"}, { "key": "id", "value": "123"}, {"key": "version", "value": "1"}]


我见过/try 过按索引访问数组中的项的各种示例,例如[0],如examples in Athena docs.但是,给定原始表的第cmsmessage列中的json/字符串,数组中的索引位置可能会有所不同.


My Failed attempt:

下面显示了我失败的try :

WITH dataset AS 
(
   SELECT *
   FROM (VALUES 
     ('{"asset": {"metadata": {"item": [{"key": "author", "value": "Rob"}, { "key": "id", "value": "123"}, {"key": "version", "value": "1"}]}}}'),
     ('{"asset": {"metadata": {"item": [{ "key": "id", "value": "456"}, {"key": "author", "value": "John"}, {"key": "version", "value": "3"}]}}}'),
     ('{"asset": {"metadata": {"item": [{"key": "version", "value": "2"}, {"key": "author", "value": "Sally"}, {"key": "id", "value": "789" }]}}}')
  ) AS t (cmsmessage)
)

SELECT
    json_extract_scalar(objArray, '$.key') as _keys,
    json_extract_scalar(objArray, '$.value') as _values
FROM dataset

CROSS JOIN UNNEST(CAST(json_extract(cmsmessage, '$.asset.metadata.item') as array(json))) as t (objArray)

推荐答案

可以说,最简单的 Select 是使用json_query,它对JSON路径语法的支持更好:

SELECT json_query(cmsmessage, 'lax $.asset.metadata.item[*]?(@.key=="id").value') AS id
    , json_query(cmsmessage, 'lax $.asset.metadata.item[*]?(@.key=="author").value') AS author
    , json_query(cmsmessage, 'lax $.asset.metadata.item[*]?(@.key=="version").value') AS version
FROM dataset;

应该适用于基于Trino的雅典娜发动机版本3.

对于版本2,您可以实现与数组操作类似的效果.

Sql相关问答推荐

LAG函数通过丢弃空值返回前一行

不可能在SQL MERGE子句中引发异常

仅 for each 唯一ID返回一个元素,并仅返回最新连接的记录

SQL:如何在表中同时使用GROUPING和CONDITION?

在SQL中为两个日期之间的每个日期添加行

使用多个嵌套数组查询JSON数据

以一致的价值获得独特的价值

将一个数组反嵌套到另外两个数组SQL中(Athena/presto)

在SELECT中将日期格式转换为双周时段

如何为缺少的类别添加行

如何根据几个条件 Select 值:如果满足一个范围的SUM,则对另一个范围求和

每个分组最多 Select 最后 2 个值并并排显示它们

从选定记录中提取摘要作为值的划分

SAS proc freq 或 proc sql 获取数据子集和整个数据的频率

日期逻辑(查找过go 90 天内的第一个匹配行)

如何在 SQL Server 中解决这个复杂的窗口查询?

BigQuery数组是否包含NULL值的判断方法

检索具有相同位置的最小和最大store 数量

BigQuery Pivot 遗漏行

BigQuery - 将 TIMESTAMP 转换为 HH:MM:SS,然后识别 TIME_DIFF