Maneira rápida e suja:http://sqlfiddle.com/#!1/bd2f6/21 Eu nomeei minha coluna
tstamp
em vez do seu timestamp
with t as (
select
generate_series(mitstamp,matstamp,'15 minutes') as int,
duration
from
(select min(tstamp) mitstamp, max(tstamp) as matstamp from tmp) a,
(select duration from tmp group by duration) b
)
select
int as timestampwindowstart,
t.duration,
count(tmp.duration)
from
t
left join tmp on
(tmp.tstamp >= t.int and
tmp.tstamp < (t.int + interval '15 minutes') and
t.duration = tmp.duration)
group by
int,
t.duration
order by
int,
t.duration
Breve explicação:
- Calcular timestamp mínimo e máximo
- Gere intervalos de 15 minutos entre o mínimo e o máximo
- Resultados de junção cruzada com valores exclusivos de duração
- Left join dados originais (left join é importante, porque isso manterá todas as combinações possíveis na saída e haverá
null
onde a duração não existe para determinado intervalo. - Dados agregados.
count(null)=0
Caso tenha mais tabelas e o algoritmo deve ser aplicado na união delas. Suponha que temos três tabelas
tmp1, tmp2, tmp3
todos com colunas tstamp
e duration
. Podemos estender a solução anterior:with
tmpout as (
select * from tmp1 union all
select * from tmp2 union all
select * from tmp3
)
,t as (
select
generate_series(mitstamp,matstamp,'15 minutes') as int,
duration
from
(select min(tstamp) mitstamp, max(tstamp) as matstamp from tmpout) a,
(select duration from tmpout group by duration) b
)
select
int as timestampwindowstart,
t.duration,
count(tmp.duration)
from
t
left join tmpout on
(tmp.tstamp >= t.int and
tmp.tstamp < (t.int + interval '15 minutes') and
t.duration = tmp.duration)
group by
int,
t.duration
order by
int,
t.duration
Você realmente deve saber
with
cláusula no PostgreSQL. É um conceito inestimável para qualquer análise de dados no PostgreSQL.