Quick and dirty
Assuming the column "timeList"
is of type time[]
, there is a quick and dirty way. Casting to varchar(5)[]
truncates the string representation of the time so that only HH24:MI remains.
test=> SELECT '{12:12, 1:1:1.123456, 23:59:59.999999}'::time[]::varchar(5)[];
varchar
---------------------
{12:12,01:01,23:59}
(1 row)
db<>fiddle here
It even represents NULL and empty array properly out of the box. Pretty clean for "quick'n'dirty".
Of course, it depends on implementation details of the text representation of time
values. But it works with any possible setting I am aware of, and I don't see it changing any time soon. Related:
Slow and sure
To format the output any way you want, there is always the slow and sure way that Laurenz provided: unnest, format, aggregate back. But it's typically faster to aggregate back right away with an ARRAY constructor in the LATERAL
subquery. This is also guaranteed to keep original order of array elements without keeping track with WITH ORDINALITY
:
SELECT *
FROM db, LATERAL (
SELECT ARRAY(SELECT to_char(unnest(db.timelist), 'HH24:MI'))
) x(times_formatted);
Plus, the aggregation the subquery always produces a row, so it will not eliminate rows with NULL or empty array ({}
) silently in the main table (like Laurenz' query does).
The implicit CROSS JOIN
still has a side effect: it converts NULL
to an empty array ({}
).
Can be avoided properly with a LEFT JOIN
like this:
SELECT *
FROM db
LEFT JOIN LATERAL (
SELECT ARRAY(SELECT to_char(unnest(db.timelist), 'HH24:MI'))
) x(times_formatted) ON db.timelist IS NOT NULL;
Consider the demo in the fiddle.
db<>fiddle here
Related: