Forma rápida y sucia:http://sqlfiddle.com/#!1/bd2f6/21 Llamé a mi columna tstamp
en lugar de su 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 explicación:
- Calcular la marca de tiempo mínima y máxima
- Generar intervalos de 15 minutos entre mínimo y máximo
- Resultados de unión cruzada con valores únicos de duración
- Datos originales de combinación izquierda (la combinación izquierda es importante, porque esto mantendrá todas las combinaciones posibles en la salida y habrá
null
) donde la duración no existe para un intervalo dado. - Datos agregados.
count(null)=0
En caso de que tenga más tablas, el algoritmo debe aplicarse en su unión. Supongamos que tenemos tres tablas tmp1, tmp2, tmp3
todos con columnas tstamp
y duration
. Podemos extender la solución 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
Realmente deberías saber with
cláusula en PostgreSQL. Es un concepto invaluable para cualquier análisis de datos en PostgreSQL.