126

On PostgreSQL 9.3.4, I have a JSON type column called "person" and the data stored in it is in the format {dogs: [{breed: <>, name: <>}, {breed: <>, name: <>}]}. I want to retrieve the breed of dog at index 0. Here are the two queries I ran:

Doesn't work

db=> select person->'dogs'->>0->'breed' from people where id = 77;
ERROR:  operator does not exist: text -> unknown
LINE 1: select person->'dogs'->>0->'bree...
                                 ^
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.

Works

select (person->'dogs'->>0)::json->'breed' from es_config_app_solutiondraft where id = 77;
 ?column?
-----------
 "westie"
(1 row)

Why is the type casting necessary? Isn't it inefficient? Am I doing something wrong or is this necessary for postgres JSON support?

1 Answer 1

208

This is because operator ->> gets JSON array element as text. You need a cast to convert its result back to JSON.

You can eliminate this redundant cast by using operator ->:

select person->'dogs'->0->'breed' from people where id = 77;
Sign up to request clarification or add additional context in comments.

3 Comments

Don't forget to review the full list of JSON operators supported by PG postgresql.org/docs/current/static/functions-json.html
what if you needed a list of all the breeds? is there support for something like select person->'dogs'->*->'breed'
@mga, see json_array_elements function. select dog->'breed' from people p, json_array_elements(p->'dogs') dog

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.