I have a table with a JSONB row which holds data in this form:
id | data |
---|---|
1 | {"key_1": "value1"} |
2 | {"another_key": "some_value"} |
Given another JSON structure like this {"key_1": ["value1", "value2"]}
, what shall I use to get the first row to match a query?
I had no luck using the JSON operators of PostgreSQL in the doc https://www.postgresql.org/docs/9.5/functions-json.html
id
, then add order by id limit 1
at the end.@@
predicate check and @?
path exists operators. If you're looking for a row with a jsonb value resembling the one you showed (key_1
with an array under it): democreate table my_table(id,jsonb_column) as values
(1::int, '{"key_1": "value1"}'::jsonb )
, (2 , '{"another_key": "some_value"}' )
, (3 , '{"key_1": ["value1", "value2"]}') ;
select * from my_table
where jsonb_column @@ '$.key_1.type()=="array"'
order by id limit 1;
id | jsonb_column |
---|---|
3 | {"key_1": ["value1", "value2"]} |
select * from my_table where jsonb_column @? '$.key_1[1]' order by id limit 1;
id | jsonb_column |
---|---|
3 | {"key_1": ["value1", "value2"]} |
@>
object containment operator instead: demoselect * from my_table where jsonb_column @> '{"key_1":[]}' order by id limit 1;
If you're looking for rows where there's key_1
on the top level, and under it, there's any of the values in your array, @Serg's example got it right. In version 14 and above, you can use [key]
subscript
select t1.*
from my_table t1
inner join jsonb_each(jsonb '{"key_1":["value1","value2"]}') as find(key,val)
on find.val @> t1.jsonb_column[find.key]
order by id limit 1;
In earlier versions, you need the ->
accessor:
select t1.*
from my_table t1
inner join jsonb_each(jsonb '{"key_1":["value1","value2"]}') as find(key,val)
on find.val @> (t1.jsonb_column -> find.key)
order by id limit 1;