add batch remove batch split batch comment selection show hidden batches hide batch highlight batch
db<>fiddle
donate feedback about
By using db<>fiddle, you agree to license everything you submit by Creative Commons CC0.
Help with an interesting Postgres question: Why isn't an Index Only Scan used on a partition accessed via the parent table?.
CREATE TABLE tbl (
tbl_id int PRIMARY KEY
, data json
);

INSERT INTO tbl VALUES
(1, '{"name": "foo", "tags": ["foo", "bar"]}')
, (2, '{"name": "empty", "tags": [null]}') -- null element
, (3, '{"name": "empty", "tags": []}') -- empty array
, (4, '{"name": "none"}'); -- no 'tags' key

-- function, see below
CREATE OR REPLACE FUNCTION json_arr2text_arr(_js json)
RETURNS text[] LANGUAGE sql IMMUTABLE AS
'SELECT ARRAY(SELECT json_array_elements_text(_js))';

TABLE tbl;
CREATE TABLE
INSERT 0 4
CREATE FUNCTION
tbl_id data
1 {"name": "foo", "tags": ["foo", "bar"]}
2 {"name": "empty", "tags": [null]}
3 {"name": "empty", "tags": []}
4 {"name": "none"}
SELECT 4
-- 9.4+ string, verbose
SELECT t.tbl_id, d.list
FROM tbl t
CROSS JOIN LATERAL (
SELECT string_agg(d.elem::text, ', ') AS list
FROM json_array_elements_text(t.data->'tags') AS d(elem)
) d;
tbl_id list
1 foo, bar
2 null
3 null
4 null
SELECT 4
-- 9.4+ string, short syntax
SELECT t.tbl_id, d.list
FROM tbl t, LATERAL (
SELECT string_agg(value::text, ', ') AS list
FROM json_array_elements_text(t.data->'tags') -- col name default: "value"
) d;
tbl_id list
1 foo, bar
2 null
3 null
4 null
SELECT 4
-- 9.4+ ARRAY constructor in correlated subquery
SELECT tbl_id, ARRAY(SELECT json_array_elements_text(t.data->'tags')) AS txt_arr
FROM tbl t;
tbl_id txt_arr
1 {foo,bar}
2 {NULL}
3 {}
4 {}
SELECT 4
-- 9.4+ custom ARRAY function
SELECT tbl_id, json_arr2text_arr(t.data->'tags') AS txt_arr
FROM tbl t;
tbl_id txt_arr
1 {foo,bar}
2 {NULL}
3 {}
4 {}
SELECT 4
-- 9.3- string, verbose (alt query)
SELECT t.tbl_id, string_agg(d.elem::text, ', ') AS list
FROM tbl t
CROSS JOIN LATERAL json_array_elements(t.data->'tags') AS d(elem)
GROUP BY t.tbl_id;
tbl_id list
1 "foo", "bar"
2 null
SELECT 2
-- 9.3- ARRAY constructor in correlated subquery
SELECT tbl_id, ARRAY(SELECT json_array_elements(t.data->'tags')) AS txt_arr
FROM tbl t;
tbl_id txt_arr
1 {""foo"",""bar""}
2 {"null"}
3 {}
4 {}
SELECT 4
-- 9.3- string, poor man's unquoting with trim()
SELECT t.tbl_id, string_agg(trim(d.elem::text, '"'), ', ') AS list
FROM tbl t, json_array_elements(t.data->'tags') d(elem)
GROUP BY 1;
tbl_id list
1 foo, bar
2 null
SELECT 2
-- 9.3- string, single row
SELECT string_agg(trim(d.elem::text, '"'), ', ') AS list
FROM tbl t, json_array_elements(t.data->'tags') d(elem)
WHERE t.tbl_id = 1;
list
foo, bar
SELECT 1
-- 9.3- string, correlated subquery
SELECT tbl_id, (SELECT string_agg(trim(value::text, '"'), ', ')
FROM json_array_elements(t.data->'tags')) AS list
FROM tbl t;
tbl_id list
1 foo, bar
2 null
3 null
4 null
SELECT 4
-- 9.3- ARRAY constructor in correlated subquery
SELECT tbl_id, ARRAY(SELECT trim(value::text, '"')
FROM json_array_elements(t.data->'tags')) AS txt_arr
FROM tbl t;
tbl_id txt_arr
1 {foo,bar}
2 {"null"}
3 {}
4 {}
SELECT 4