Reputation: 2168
I have a table with the following structure -
Column Name | Data Type
--------------------------
user_id | uuid
profile | jsonb
An example profile field would be something like -
{ "data": { "races": [ "white", "asian" ] } }
I want to query this table for users contain one of the following races (for example) - "white", "african american"
I would expect my example user above to be returned since their races field contains "white".
I have tried something like this with no success -
SELECT user_id from table
WHERE profile -> 'data' ->> 'races' = ANY('{"white", "african american"}')
Using Postgres 13.x
Thank you!
Upvotes: 0
Views: 1268
Reputation: 164679
tl;dr use the ?|
operator.
There's two problems with your query.
->>
returns text
not jsonb. So you're asking if the text ["white", "asian"]
matches white
or african american
.
You probably did that because otherwise you got type errors trying to use any
with JSONB. any
wants a Postgres array of things to compare, and it has to be an array of jsonb. We can do that...
select user_id
from user
where profile -> 'data' -> 'races' = ANY(array['"white"', '"african american"']::jsonb[]);
But this has the same problem as before, it's checking if the json array [ "white", "asian" ]
equals "white"
or "african american"
.
You need an operator which will match against each element of the JSON. Use the ?|
operator.
select user_id
from users
where profile -> 'data' -> 'races' ?| array['white', 'african american'];
Upvotes: 1
Reputation: 121534
Use the ?|
operator:
select user_id
from my_table
where profile -> 'data' -> 'races' ?| array['white', 'african american']
According to the documentation:
jsonb ?| text[] -> boolean
Do any of the strings in the text array exist as top-level keys or array elements?
Upvotes: 2