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