DISTINCT
is neither a function nor an operator but an SQL construct or syntax element. Can be added as leading keyword to the whole SELECT
list or within most aggregate functions.
Add it to the SELECT
list (consisting of a single column in your case) in a subselect where you can also cheaply add ORDER BY
. Should yield best performance:
SELECT string_agg(to_char(the_date, 'DD-MM-YYYY'), ',') AS the_dates
FROM (
SELECT DISTINCT to_timestamp(from_date / 1000)::date AS the_date
FROM trn_day_bookkeeping_income_expense
WHERE enterprise_id = 5134650
ORDER BY the_date -- assuming this is the order you want
) sub;
First generate dates (multiple distinct values may result in the same date!).
Then the DISTINCT
step (or GROUP BY
).
(While being at it, optionally add ORDER BY
.)
Finally aggregate.
An index on (enterprise_id)
or better (enterprise_id, from_date)
should greatly improve performance.
Ideally, timestamps are stored as type timestamp
to begin with. Or timestamptz
. See:
DISTINCT ON
is a Postgres-specific extension of standard SQL DISTINCT
functionality. See:
Alternatively, you could also add DISTINCT
(and ORDER BY
) to the aggregate function string_agg()
directly:
SELECT string_agg(DISTINCT to_char(to_timestamp(from_date / 1000), 'DD-MM-YYYY'), ',' ORDER BY to_char(to_timestamp(from_date / 1000), 'DD-MM-YYYY')) AS the_dates
FROM trn_day_bookkeeping_income_expense
WHERE enterprise_id = 5134650
But that would be ugly, hard to read and maintain, and more expensive. (Test with EXPLAIN ANALYZE
).