10

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

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

How can we write query which will select row if "data" contains "city"

JSON structure of data is not consistent.

3 Answers 3

30

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.

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

1 Comment

This works on a JSONB column. The question is about a JSON column, so you have to do a type cast: SELECT * FROM details WHERE data::JSONB ? 'city';
2

You can use ?:

SELECT *
FROM "details" 
WHERE data->'country'->'state' ? 'city';

Comments

-3

You can convert your json to text and search for the key with LIKE

SELECT *
FROM "details"
WHERE "data"::text LIKE '%"city":%'

3 Comments

some json value may contain 'city' text. How you distinguish is this key name or just text?
well this works for my case where value is a list like this ["abc", "edf"]
This query will have a performance degradation as compared to accepted answer.

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.