Я не уверен, что это именно то, что вы ищете, но, возможно, это может послужить основой для адаптации.
У меня часто есть потребность в создании сводных данных за периоды времени, хотя я не использую время эпохи, поэтому могут быть более эффективные способы манипулирования значениями, чем я придумал.
создать и заполнить тестовую таблицу
create table epoch_t(etime numeric);
insert into epoch_t
select extract(epoch from generate_series(now(),now() - interval '6 hours',interval '-10 minutes'));
Чтобы разделить время на периоды:
select generate_series(to_char(now(),'yyyy-mm-dd hh24:00:00')::timestamptz,
to_char(now(),'yyyy-mm-dd hh24:00:00')::timestamptz - interval '4 hours',
interval '-1 hour');
Преобразование времени эпохи в метку времени postgres:
select timestamptz 'epoch' + etime * '1 second'::interval from epoch_t;
затем усечь до часа:
select to_char(timestamptz 'epoch' + etime * '1 second'::interval,
'yyyy-mm-dd hh24:00:00')::timestamptz from epoch_t
Чтобы предоставить сводную информацию по часам:
select to_char(timestamptz 'epoch' + etime * '1 second'::interval,
'yyyy-mm-dd hh24:00:00')::timestamptz,
count(*)
from epoch_t
group by 1
order by 1 desc;
Если у вас могут быть пропуски в данных, но вам необходимо сообщить о нулевых результатах, используйте generate_series для создания периодов и оставьте соединение с таблицей данных.
В этом случае я создаю образцы часовых сегментов назад до совокупности данных выше - 9 часов вместо 6 и присоединяюсь к преобразованию времени эпохи в метку времени, усеченную до часа.
select per.sample_hour,
sum(case etime is null when true then 0 else 1 end) as etcount
from (select generate_series(to_char(now(),
'yyyy-mm-dd hh24:00:00')::timestamptz,
to_char(now(),'yyyy-mm-dd hh24:00:00')::timestamptz - interval '9 hours',
interval '-1 hour') as sample_hour) as per
left join epoch_t on to_char(timestamptz 'epoch' + etime * '1 second'::interval,
'yyyy-mm-dd hh24:00:00')::timestamptz = per.sample_hour
group by per.sample_hour
order by per.sample_hour desc;