2

I have a column with type jsonb holding a list of IDs as plain JSON array in my PostgreSQL 9.6.6 database and I want to search this field based on any ID in the list. How to query write this query?

'[1,8,3,4,56,6]'

For example, my table is:

CREATE TABLE mytable (
    id bigint NOT NULL,
    numbers jsonb
);

And it has some values:

 id  |  numbers
-----+-------
 1   | "[1,8,3,4,56,6]"
 2   | "[1,2,7,4,24,5]"

I want something like this:

SELECT * 
FROM mytable
WHERE
id = 1
AND
numbers::json->>VALUE(56)
;

Expected result (only if the JSON array has 56 as element):

 id  |  numbers
-----+-------
 1   | "[1,8,3,4,56,6]"

Step-2 problem :

The result of this command is TRUE :

SELECT '[1,8,3,4,56,6]'::jsonb @> '56';

but already when I use

SELECT * 
FROM   mytable
numbers::jsonb @> '[56]';

or

SELECT * 
FROM   mytable
numbers::jsonb @> '56';

or

SELECT * 
FROM   mytable
numbers::jsonb @> '[56]'::jsonb;

The result is nothing :

 id  |  numbers
-----+-------
(0 rows)

Instead of be this :

 id  |  numbers
-----+-------
 1   | "[1,8,3,4,56,6]"

I find why I get (0 rows) ! :))

because I insert jsonb value to mytable with double quotation , in fact this is correct value format (without double quotation ):

 id  |  numbers
-----+-------
 1   | [1,8,3,4,56,6]
 2   | [1,2,7,4,24,5] 

now when run this command:

SELECT * 
FROM   mytable
numbers @> '56';

The result is :

 id  |  numbers
-----+-------
 1   | [1,8,3,4,56,6]

1 Answer 1

4

Use the jsonb "contains" operator @>:

SELECT * 
FROM   mytable
WHERE  id = 1
AND    numbers @> '[56]';

Or

...
AND    numbers @> '56';

fiddle

Works with or without enclosing array brackets in this case.

If your table is big, consider an index. See:

To address your comment: when testing with string literals, be sure to add an explicit cast:

SELECT '[1,8,3,4,56,6]'::jsonb @> '56';

If you don't, Postgres does not know which data type to assume. There are multiple options:

SELECT '[1,8,3,4,56,6]' @> '56';

ERROR:  operator is not unique: unknown @> unknown

Related:

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

5 Comments

I get this error : ERROR : operator is not unique: unknown @> unknown HINT: Could not choose a best candidate operator ...
@MojtabaArvin: Doesn't make sense. I tested in Postgres 9.6, it's working. What's your version of Postgres? (Should be in the question to begin with.)
You would't get unknown in the error msg if the column is type jsonb. You probably tested with untyped string literals, which is misleading.
How do I search for multiple values like AND numbers @> '[56,4]'; How do I search for any values from AND numbers @> '[56]' OR '[4]';
@ajitpawarink: One way: numbers @> ANY ('{56, 4}'::jsonb[]), which is short for (numbers @> '56'::jsonb OR numbers @> '7'::jsonb); Or numbers @? '$[*] ? (@ == 56 || @ == 7)'. Unfortunately, numbers ?| '{56, 7}'::text[] only works for string elements, not for numeric elements. Start a separate question if you need more details.

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.