0

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!

2
  • You have a typo in your JSONB. The key is data:. It should be data. That doesn't fix your problem. Commented Jan 13, 2022 at 23:15
  • Good catch. Just fixed. Any thoughts on a solution to this problem @Schwern? Commented Jan 13, 2022 at 23:17

2 Answers 2

2

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?

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

Comments

1

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

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.