Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgresql JSON column check key exists

I have wrote query like this to check json column has key

SELECT *
FROM "details" 
where ("data"->'country'->'state'->>'city') is not null; 

but i need to write query which will select row if "data" contains "city"

json structure of data is not consistent.

like image 790
Aniket Kulkarni Avatar asked Mar 24 '16 07:03

Aniket Kulkarni


People also ask

How do I check if a JSON key exists in Postgres?

In Postgres, if you select a key that does not exist it will return null. so u can check the existence of a key by checking the null value of that key.

How do I query a JSON column in PostgreSQL?

PostgreSQL has two native operators -> and ->> to query JSON documents. The first operator -> returns a JSON object, while the operator ->> returns text. These operators work on both JSON as well as JSONB columns. There are additional operators available for JSONB columns.

What is -> in PostgreSQL?

PostgreSQL provides two native operators -> and ->> to help you query JSON data. The operator -> returns JSON object field as JSON. The operator ->> returns JSON object field as text.

What is Json_build_object?

json_build_object(VARIADIC "any") Builds a JSON object out of a variadic argument list. By convention, the argument list consists of alternating keys and values.


Video Answer


2 Answers

You can check the top-level keys of data with ? as it is said in the documentation.

For example

SELECT * FROM details
WHERE data ? 'city';

Checking every key in all nested objects from the json column requires a recursive CTE

select * from details
where 'city' in (
    WITH RECURSIVE t(k,j) as (
        select jsonb_object_keys(details.data), details.data
    UNION ALL
        select jsonb_object_keys(t.j->t.k), t.j->t.k
        FROM t WHERE jsonb_typeof(t.j->t.k) = 'object'
    )
    select k from t
);

This of course is not very efficient.

like image 90
Sevanteri Avatar answered Oct 17 '22 17:10

Sevanteri


You can use ?:

SELECT *
FROM "details" 
WHERE data->'country'->'state' ? 'city';
like image 38
TitanFighter Avatar answered Oct 17 '22 15:10

TitanFighter