I have this table:
postgres::DATABASE=> SELECT * FROM db;
timeList | time
---------+------------+---------------------
{11:00:00,12:00:00} | 11:22:33
{19:00:00} | 12:12:33
I need to select timeList
values without seconds. But receive this error:
postgres::DATABASE=> SELECT TO_CHAR(timeList, 'HH24:MI') timeList FROM db;
ERROR: syntax error at or near "timeList"
LINE 1: SELECT TO_CHAR(time, 'HH24:MI') timeList FROM db;
^
Command to select single value works as expected:
postgres::DATABASE=> SELECT TO_CHAR(time, 'HH24:MI') time FROM db;
time
-------
11:22
12:12
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:
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:
Because of your denormalized data model, you have to use unnest
and array_agg
:
SELECT array_agg(to_char(tl.tle, 'HH24:MI') ORDER BY tl.n),
to_char(db.time, 'HH24:MI')
FROM db
CROSS JOIN LATERAL unnest(db.timelist) WITH ORDINALITY AS tl(tle, n)
GROUP BY db;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.