17

我正在使用最新的(0.117)Presto 并尝试使用这样的复杂 JSON 数组执行CROSS JOIN UNNEST 。

[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}, ...]

为此,首先我尝试使用id的值创建一个ARRAY

SELECT CAST(JSON_EXTRACT('[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}]', '$..id') AS ARRAY<BIGINT>)

但它不起作用。

提取id值的最佳 JSON 路径是什么?

4

4 回答 4

14

您可以将 JSON 转换为 MAP 的数组,并使用transformlambda 函数提取“id”键:

select 
        TRANSFORM(CAST(JSON_PARSE(arr1) AS ARRAY<MAP<VARCHAR, VARCHAR>>), entry->entry['id'])
from 
       (values ('[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}]')) t(arr1)

输出:

 [1, 2]
于 2017-06-01T20:35:15.853 回答
13

这将解决您的问题。它更通用地转换为 json 数组(在给定任意映射结构的情况下不太容易出错):

select 
        TRANSFORM(CAST(JSON_PARSE(arr1) AS ARRAY<JSON>), 
                   x -> JSON_EXTRACT_SCALAR(x, '$.id'))
from 
       (values ('[{"id": 1, "value":"xxx"}, {"id":2, "value":"yy"}]')) t(arr1)

快速输出:

 [1,2]

...我遇到了一个 json 列表嵌套在 json 中的情况。我的 json 列表有一个模棱两可的嵌套地图结构。以下代码返回给定 json 列表中特定键的值数组。

  1. 使用 JSON EXTRACT 提取列表
  2. 将列表转换为 json 数组
  3. 使用 TRANSFORM 函数循环遍历数组中的 json 元素,并提取您感兴趣的键的值。

>

TRANSFORM(CAST(JSON_EXTRACT(json, '$.path.toListOfJSONs') AS ARRAY<JSON>),
          x -> JSON_EXTRACT_SCALAR(x, '$.id')) as id
于 2018-05-29T18:35:44.517 回答
5

现在,您可以使用presto-third-functions,它提供json_array_extract功能,您可以像这样提取 json 数组信息:

    select 
           json_array_extract_scalar(arr1, '$.book.id') 
    from 
           (values ('[{"book":{"id":"12"}}, {"book":{"id":"14"}}]')) t(arr1)

输出是:

    [12, 14]
于 2016-07-25T02:53:36.523 回答
2

我终于放弃了寻找一个简单的 JSON 路径来提取它们。

相反,我编写了如下所示的冗余脏查询来完成任务。

SELECT
  ...
FROM
  (
    SELECT
      SLICE(ARRAY[
        JSON_EXTRACT(json_column, '$[0].id'),
        JSON_EXTRACT(json_column, '$[1].id'),
        JSON_EXTRACT(json_column, '$[2].id'),
        ...
      ], JSON_ARRAY_LENGTH(json_column)) ids
    FROM
     the.table
  ) t1
  CROSS JOIN UNNEST(ids) AS t2(id)
WHERE
  ...

如果您知道另一种交叉加入它们的好方法,我仍然想知道最佳实践!

于 2015-09-11T02:26:24.800 回答