t=# with c(id,data) as (values(1,'[{"279863":"500040004","awb_no":"18171917033930"},{"279864":"500040003","awb_no":"18171917033931"}]'::json))
select id,json_object_keys(json_array_elements(data)) = '279864' from c;
id | ?column?
----+----------
1 | f
1 | f
1 | t
1 | f
(4 rows)
so you can check with WHERE EXISTS or count(*) > 0 or any another way you like...
eg, with bool_or (if at least one is true, group is true):
t=# with c(id,data) as (values(1,'[{"279863":"500040004","awb_no":"18171917033930"},{"279864":"500040003","awb_no":"18171917033931"}]'::json))
, m as (select id,(json_object_keys(json_array_elements(data)) = '279864')j from c)
select id, bool_or(j) from m group by id;
id | bool_or
----+---------
1 | t
(1 row)
So in short:
- use
json_array_elements to divide array for check.
- use
json_object_keys toget the key of divided array element
- use bool_or to check if at least one key is like pattern
update as OP is asking for "less complicated" solution, I post a monkey hack as well:
t=# with c(id,data) as (values(1,'[{"279863":"500040004","awb_no":"18171917033930"},{"279864":"500040003","awb_no":"18171917033931"}]'::json))
select * from c where data::jsonb::text ~ '(,)|({ )"279863":';
id | data
----+-----------------------------------------------------------------------------------------------------
1 | [{"279863":"500040004","awb_no":"18171917033930"},{"279864":"500040003","awb_no":"18171917033931"}]
(1 row)
which is of course is very slippery and requires some explanation as well:
- I need to cast to
jsonb first to eliminate possible syntax freedom
- json object keys are not sorted, thus I need to catch both
{{ and , cases