Reputation: 121
I have a "contact_info" column that stores jsonb, which look like this:
[ {"phoneNumber":"123-4567", "emailAddress":"[email protected]"} ]
I'm trying to retrieve all the rows where phone number equals "123-4567".
How can I do this in a one-line query? I can return the whole column with SELECT contact_info FROM db_name.db_table;
but haven't had success pulling the individual objects and querying the phone numbers inside.
I've been looking at [this question][1] but it is slightly different than my situation (list of json objects vs json object containing a list), and I can't figure out how to apply the solution to my version of the issue.
Upvotes: 0
Views: 113
Reputation: 65353
You can use JSONB_ARRAY_ELEMENTS()
function as
SELECT t.*
FROM t
CROSS JOIN JSONB_ARRAY_ELEMENTS(contact_info) AS js(elm)
WHERE js.elm ->> 'phoneNumber' = '123-4567'
Upvotes: 1
Reputation: 222572
If all of your arrays have just one element, this is straight-forward:
select t.*, t.contact_info -> 0 ->> 'emailAddress' as email_address
from db_table t
where t.contact_info -> 0 ->> 'phoneNumber' = '123-4567'
Else, can use jsonb_array_elements()
and a lateral join to unnest the array, then filter:
select t.*, x.obj ->> 'emailAddress' as email_address
from db_table t
cross join lateral jsonb_array_elements(t.contact_info) x(obj)
where x.obj ->> 'phoneNumber' = '123-4567'
Note that this returns multiple rows if more than one object in a given array matches on the phone number. If you want to avoid that, you can use a subquery:
select t.*, x.obj ->> 'emailAddress' as email_address
from db_table t
where exists (
select 1
from jsonb_array_elements(t.contact_info) x(obj)
where x.obj ->> 'phoneNumber' = '123-4567'
)
Upvotes: 1