Much simpler, yet:
CREATE OR REPLACE FUNCTION week_dates(_week integer, _year integer)
RETURNS SETOF date AS
$func$
SELECT date_trunc('week', ($2::text || '-1-4')::timestamp)::date
+ 7 * ($1 - 1) -- fix off-by-one
+ generate_series (0,6)
$func$ LANGUAGE sql;
The major point is that you can add integer
to date
to increment days in PostgreSQL.
date_trunc()
returns a timestamp
, so we need to cast to date
another time.
I start with the 4th of January because (quoting the manual here):
By definition (ISO 8601), weeks start on Mondays and the first week of a year contains January 4 of that year.
The function happily accepts impossible weeks like -1
or 55
and returns a somewhat reasonable result. To disallow that, I would make it a plpgsql function and check the input values.
This returns a set instead of an array. It's trivial to make it an array instead (SELECT ARRAY(SELECT ...
). But this should be faster. Your query could look like this:
SELECT *
FROM some_report_cache_table
JOIN week_dates(1, 2013) w("date") USING ("date")
Aside: You shouldn't use date
as column name, since it is a reserved word in SQL.