1

I have a jsonb field with an array like this one below:

[  
   {  
      "type":"discount",
      "title":"Discount 10%"
   },
   {        
      "file":"zx5rP8EoacyfhqGndcSOnP8VYtkr9Ya8Nvf7oYL98YDsM1CLMYIurYvfVUU4AGkzBsovwssT0bq.pdf",
      "type":"menu",
      "title":"Some menu title etc"
   }
]

I want to get the file attribute in case there is a type=menu in the array.

What I managed to do is to know if there is one, but how can I eventually extract the file value?

case when offers @> '[{"type":"menu"}]' then true else false end

I don't want to do something like this below because the array may not contain a discount type.

offers->1->'file'
2
  • try json_array_elements for this?.. Commented Feb 9, 2017 at 11:55
  • @VaoTsun no luck there Commented Feb 9, 2017 at 12:03

2 Answers 2

5

Use jsob_array_elements() and ->> operator (see JSON Functions and Operators.)

with a_table(json_col) as (
values (
'[  
   {  
      "type":"discount",
      "title":"Discount 10%"
   },
   {        
      "file":"zx5rP8EoacyfhqGndcSOnP8VYtkr9Ya8Nvf7oYL98YDsM1CLMYIurYvfVUU4AGkzBsovwssT0bq.pdf",
      "type":"menu",
      "title":"Some menu title etc"
   }
]'::jsonb)
)

select value->>'file' as filename
from a_table,
lateral jsonb_array_elements(json_col)
where value->>'type' = 'menu'

                                    filename                                     
---------------------------------------------------------------------------------
 zx5rP8EoacyfhqGndcSOnP8VYtkr9Ya8Nvf7oYL98YDsM1CLMYIurYvfVUU4AGkzBsovwssT0bq.pdf
(1 row)
Sign up to request clarification or add additional context in comments.

2 Comments

why do you use lateral instead of plain jsonb_array_elements ?
Functions that return set of rows should be called in the FROM clause and lateral join is a natural way to do that.
1

Eg:

t=# with a as (with v as (select '[
   {
      "type":"discount",
      "title":"Discount 10%"
   },
   {
      "file":"zx5rP8EoacyfhqGndcSOnP8VYtkr9Ya8Nvf7oYL98YDsM1CLMYIurYvfVUU4AGkzBsovwssT0bq.pdf",
      "type":"menu",
      "title":"Some menu title etc"
   }
]'::jsonb j)
select jsonb_array_elements(j) r from v) select r->>'file' from a where r->>'type' = 'menu';
                                    ?column?
---------------------------------------------------------------------------------
 zx5rP8EoacyfhqGndcSOnP8VYtkr9Ya8Nvf7oYL98YDsM1CLMYIurYvfVUU4AGkzBsovwssT0bq.pdf
(1 row)

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.