Hurtig og beskidt måde:http://sqlfiddle.com/#!1/bd2f6/21 Jeg gav min kolonne navnet tstamp
i stedet for dit 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
Kort forklaring:
- Beregn minimum og maksimum tidsstempel
- Generer 15 minutters intervaller mellem minimum og maksimum
- Cross join-resultater med unikke værdier for varighed
- Original data til venstre joinforbindelse (venstre joinforbindelse er vigtig, fordi dette vil beholde alle mulige kombinationer i output, og der vil være
null
hvor varigheden ikke eksisterer for et givet interval. - Samlede data.
count(null)=0
I tilfælde af at du har flere tabeller, og algoritmen skal anvendes på deres forening. Antag, at vi har tre tabeller tmp1, tmp2, tmp3
alle med kolonner tstamp
og duration
. Vi kan udvide den tidligere løsning:
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
Du burde virkelig kende with
klausul i PostgreSQL. Det er et uvurderligt koncept for enhver dataanalyse i PostgreSQL.