En PostgreSQL, supongamos que queremos generar todos los períodos mensuales entre ‘2015-09-12 23:50:00’ y ‘2015-11-22 00:20:00’ con corte al inicio del día 8.
Se puede crear la siguiente función:
CREATE OR REPLACE FUNCTION generate_timedivisions(ts_start timestamp, ts_end timestamp, period varchar, period_offset interval = '0') RETURNS TABLE(tr_start timestamp, tr_end timestamp) AS $$
DECLARE
end_of_test_interval timestamp;
BEGIN
SELECT date_trunc(period, ts_start) + ('1 ' || period)::interval + period_offset INTO end_of_test_interval;
WHILE end_of_test_interval < ts_end LOOP
RETURN QUERY SELECT ts_start, end_of_test_interval;
ts_start = end_of_test_interval;
end_of_test_interval := ts_start + ('1 ' || period)::interval;
END LOOP;
RETURN QUERY SELECT ts_start, ts_end;
END;
$$ LANGUAGE plpgsql;
Y usarla de esta manera:
-- Obsérvese que se usa '7 day' y no '8 day' por las siguientes razones:
-- 1. los días comienzan a contarse con 1.
-- 2. el último parámetro es 'interval'
-- 3. Se pide el corte al *inicio* del día 8.
SELECT * from generate_timedivisions('2015-09-12 23:50:00', '2015-11-22 00:20:00', 'month', '7 day');
tr_start | tr_end
---------------------+---------------------
2015-09-12 23:50:00 | 2015-10-08 00:00:00
2015-10-08 00:00:00 | 2015-11-08 00:00:00
2015-11-08 00:00:00 | 2015-11-22 00:20:00