1

I am trying to parse a JSON text using JSON_EXTRACT_PATH_TEXT() function. JSON sample:

{ 
   "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. Can anyone help, please? Thanks

2 Answers 2

4

This is a rather complicated task in Redshift, that, unlike Postgres, has poor support to manage JSON, and no function to unnest arrays.

Here is one way to do it using a number table; you need to populate the table with incrementing numbers starting at 0, like:

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():

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';
Sign up to request clarification or add additional context in comments.

Comments

1

You'll need to use json_array_elements for that:

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
      }]}');

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.