5

I have been searching for this answer for long on stackoverflow, but did not find anything useful. I have data in my_tbl as:

folder_id |  links                                                                                                     
--------------+----------------------------------------------------------------
   761 | [{"ids": "[82293,82292]", "index": "index_1"}, {"ids": "[82293,82292]", "index": "index_2"}]
   769 | [{"ids": "[82323,82324]", "index": "index_3"}]
   572 | [{"ids": "[80031,79674,78971]", "index": "index_4"}]
   785 | [{"ids": "[82367,82369]", "index": "index_5"}, {"ids": "[82368,82371]", "index": "index_6"}]
   768 | [{"ids": "[82292,82306]", "index": "index_7"}]

I want to get all the rows where links->>'ids' contain 82292. So in this case, it should return me folder_id 761 and 768.

I achieved so far is separating ids arrays from links by - jsonb_array_elements(links) ->> 'ids'

not sure how to proceed further.

0

1 Answer 1

14

You can use jsonb_array_elements to convert a json array to a rowset. You can use this to at the value of "ids". Using the @> operator you can check if the array contains a value:

select  distinct folder_id
from    YourTable
cross join lateral
        jsonb_array_elements(links) ids(ele)      
where   (ele->>'ids')::jsonb @> '[82292]'

A tricky part is that "[82293,82292]" is stored as a string, not an array. The ele->>'ids' expression retrieves "[82293,82292]" as string using the ->> operator (the double > makes it return text instead of jsonb.) The content of the string is converted to an array by ::jsonb.

Example at rextester.com.

Sign up to request clarification or add additional context in comments.

4 Comments

Also, something I tried to get more out of the query -> search array of elements; something like, ele.id IN ('82292', '82324') that works too.
Looks like you can do that with @>, check if the left-hand side array contains the right-hand side array
Really like the use of the cross join lateral - nice solution.
Hi Andomar. This solution is really helpful. If you are trying to check if links has multiple ids, then this seems to work in Postgres 11.10. where (ele->>'ids')::jsonb @> '[82292]' AND (ele->>'ids')::jsonb @> '[82306]' However, on my machine with Postgres 12.3 this results in 0 rows returned. Do you know why this may not be working on a later version?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.