You can use the function json_array_elements()
to unnest the JSON array and string_agg()
to build a text
array from it.
You need columns to uniquely identify each row. The primary key would be your natural choice. If you should not have one, the ctid
can be your surrogate primary key for the purpose of this query.
Text array with double-quoted values:
SELECT t.tbl_id, string_agg(elem::text, ', ') AS list
FROM tbl t, json_array_elements(t.j->'tags') elem
GROUP BY 1;
This is making use of the implicit LATERAL JOIN
in Postgres 9.3 or later!
Poor man's unquoting with trim()
:
SELECT t.tbl_id, string_agg(trim(elem::text, '"'), ', ') AS list
FROM tbl t, json_array_elements(t.j->'tags') elem
GROUP BY 1;
Extract a single value:
SELECT string_agg(trim(elem, '"'), ', ') AS list
FROM tbl t, json_array_elements(t.j->'tags') elem
WHERE tbl_id = 1;
SQL Fiddle For the last two queries.
The first query does not agree with SQLfiddle but it runs on my local 9.3 installation.
Note:
We would need a json_array_elements_text(json)
, the twin of json_array_elements(json)
to return proper text
values from a JSON array. But that seems to be missing from the provided arsenal of JSON functions. Or some other function to extract a text
value from a scalar JSON
value. I seem to be missing that one, too.
So I improvised with trim()
, but that will fail for non-trivial cases ...
Update for pg 9.4
Obviously inspired by this post, the Postgres 9.4 provides exactly the function I was wishing for: json_array_elements_text(json)
and jsonb_array_elements_text(jsonb)
.
Thanks to Laurence Rowe for providing a patch and Andrew Dunstan for committing it!
So:
SELECT t.tbl_id, string_agg(elem, ', ') AS list
FROM tbl t, json_array_elements_text(t.j->'tags') elem
GROUP BY 1;
Or jsonb_array_elements_text(jsonb)
for jsonb
.
Related anser on SO.
json_extract_path_text(your_column, 'tags')
what you are looking for? – a_horse_with_no_name Dec 2 '13 at 21:45