简体   繁体   English

Redshift Postgresql - 如何解析嵌套的 JSON

[英]Redshift Postgresql - How to Parse Nested JSON

I am trying to parse a JSON text using JSON_EXTRACT_PATH_TEXT() function.我正在尝试使用 JSON_EXTRACT_PATH_TEXT() 函数解析 JSON 文本。 JSON sample: JSON 示例:

{ 
   "data":[ 
      { 
         "name":"ping",
         "idx":0,
         "cnt":27,
         "min":16,
         "max":33,
         "avg":24.67,
         "dev":5.05
      },
      { 
         "name":"late",
         "idx":0,
         "cnt":27,
         "min":8,
         "max":17,
         "avg":12.59,
         "dev":2.63
      }
   ]
}
'

I tried JSON_EXTRACT_PATH_TEXT(event , '{"name":"late"}', 'avg') function to get 'avg' for name = "late", but it returns blank.我尝试了 JSON_EXTRACT_PATH_TEXT(event , '{"name":"late"}', 'avg')函数来获取 name = "late" 的 'avg',但它返回空白。 Can anyone help, please?有人可以帮忙吗? Thanks谢谢

This is a rather complicated task in Redshift, that, unlike Postgres, has poor support to manage JSON , and no function to unnest arrays.这是 Redshift 中一项相当复杂的任务,与 Postgres 不同,它对管理 JSON 的支持很差,并且没有取消嵌套数组的功能。

Here is one way to do it using a number table;这是使用数字表的一种方法; you need to populate the table with incrementing numbers starting at 0 , like:您需要使用从0开始的递增数字填充表格,例如:

create table nums as
    select 0 i union all select 1 union all select 2 union all select 3 
    union all select 4 union all select 5 n union all select 6 
    union all select 7 union all select 8 union all select 9
;

Once the table is created, you can use it to walk the JSON array using json_extract_array_element_text() , and check its content with json_extract_path_text() :创建表后,您可以使用 json_extract_array_element_text() 遍历 JSON 数组,并使用json_extract_array_element_text() json_extract_path_text()其内容:

select json_extract_path_text(item, 'avg') as my_avg
from (
    select json_extract_array_element_text(t.items, n.i, true) as item
    from (
        select json_extract_path_text(mycol, 'data', true ) as items
        from mytable
    ) t
    inner join nums n on n.i < json_array_length(t.items, true)
) t
where json_extract_path_text(item, 'name') = 'late';

You'll need to use json_array_elements for that:您需要为此使用json_array_elements

select obj->'avg'
  from foo f, json_array_elements(f.event->'data') obj 
where obj->>'name' = 'late';

Working example工作示例

create table foo (id int, event json);
insert into foo values (1,'{ 
   "data":[ 
      { 
         "name":"ping",
         "idx":0,
         "cnt":27,
         "min":16,
         "max":33,
         "avg":24.67,
         "dev":5.05
      },
      { 
         "name":"late",
         "idx":0,
         "cnt":27,
         "min":8,
         "max":17,
         "avg":12.59,
         "dev":2.63
      }]}');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM