Here is my table (simplified, only significant columns):
CREATE TABLE things (
id serial primary key
, name varchar
, blueprint json default '{}'
);
And some sample data:
# select * from things;
id | name | blueprint
----+---------+-----------------------------------------------------------------------------
1 | Thing 1 | {}
2 | Thing 2 | {"1":{"name":"Iskapola","wight":"2"}}
3 | Thing 3 | {"1":{"name":"Azamund","weight":"3"}, "2":{"name":"Iskapola","weight":"1"}}
4 | Thing 4 | {"1":{"name":"Ulamir","weight":"1"}, "2":{"name":"Azamund","weight":"1"}}
I'd like to select rows that have 'Azamund' anywhere under the name key.
Something like this:
# select * from things where * ->> 'name' = 'Azamund';
id | blueprint
----+----------------------------------------------------------------------------
7 | {"1":{"name":"Azamund","weight":"3"}, "2":{"name":"Iskapola","weight":"1"}}
8 | {"1":{"name":"Ulamir","weight":"1"}, "2":{"name":"Azamund","weight":"1"}}
Data is nested exactly like in the sample (only one level).
Currently we are using PostgreSQL 9.3.5.
Is it possible in PostgreSQL 9.3? Maybe 9.4?
Your query is close. json_each() is the key function. Or jsonb_each() for jsonb. A couple of improvements:
SELECT *
FROM things t
WHERE EXISTS (
SELECT FROM json_each(t.blueprint) b
WHERE b.value->>'name' ILIKE 'azamund'
);
Old sqlfiddle
db<>fiddle here
json_each() already returns the value as json data type. No need for an additional cast.
Better, yet, use a LATERAL reference in EXISTS. This is much cleaner than unnesting with a set-returning function in the SELECT list. Related:
Use ILIKE (~~*) for the pattern match. Regular expression matches (~, ~*) are more powerful, but also more expensive. So use the basic LIKE / ILKE where you can. Details:
You have already seen my related answer for JSON arrays:
While the query for nested JSON objects seems just as simple, there is superior index support for the array:
May get simpler / more efficient with SQL/JSON in Postgres 12 ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With