You don't need a CTE for this, that would be more expensive than necessary.
And you don't need to cast to timestamp
, the result already is of data type timestamp
when you feed timestamp
types to generate_series()
. Details here:
In Postgres 9.3 or later you can use a LATERAL
join:
SELECT to_char(ts, 'YYYY-MM-DD HH24') AS formatted_ts
FROM (
SELECT min(start_timestamp) as first_date
, max(start_timestamp) as last_date
FROM header_table
) h
, generate_series(h.first_date, h.last_date, interval '1 hour') g(ts);
Optionally with to_char()
to get the result as text in the format you mentioned.
This works in any Postgres version:
SELECT generate_series(min(start_timestamp)
, max(start_timestamp)
, interval '1 hour') AS ts
FROM header_table;
Typically a bit faster.
Calling set-returning functions in the SELECT
list is a non-standard-SQL feature and frowned upon by some. Also, there were behavioral oddities (though not for this simple case) that were eventually fixed in Postgres 10. See:
Note a subtle difference in NULL handling:
The equivalent of
max(start_timestamp)
is obtained with
ORDER BY start_timestamp DESC NULLS LAST
LIMIT 1
Without NULLS LAST
NULL values come first in descending order (if there can be NULL values in start_timestamp
). You would get NULL for last_date
and your query would come up empty.
Details:
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…