Schnell und schmutzig:http://sqlfiddle.com/#!1/bd2f6/21 Ich habe meine Spalte tstamp
genannt anstelle Ihres 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
Kurze Erklärung:
- Minimalen und maximalen Zeitstempel berechnen
- Generieren Sie 15-Minuten-Intervalle zwischen Minimum und Maximum
- Cross-Join-Ergebnisse mit eindeutigen Dauerwerten
- Linksverknüpfung der Originaldaten (Linksverknüpfung ist wichtig, da dadurch alle möglichen Kombinationen in der Ausgabe beibehalten werden und
null
vorhanden sein wird wobei die Dauer für ein bestimmtes Intervall nicht existiert. - Aggregierte Daten.
count(null)=0
Falls Sie mehr Tabellen haben und der Algorithmus auf deren Vereinigung angewendet werden soll. Angenommen, wir haben drei Tabellen tmp1, tmp2, tmp3
alle mit Spalten tstamp
und duration
. Dann können wir die vorherige Lösung erweitern:
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
Sie sollten with
wirklich kennen -Klausel in PostgreSQL. Es ist ein unschätzbares Konzept für jede Datenanalyse in PostgreSQL.