Snelle en vuile manier:http://sqlfiddle.com/#!1/bd2f6/21 Ik noemde mijn kolom tstamp
in plaats van uw 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
Korte uitleg:
- Bereken minimum en maximum tijdstempel
- Genereer intervallen van 15 minuten tussen minimum en maximum
- Cross-join resultaten met unieke waarden van duur
- Originele data linker join (linker join is belangrijk, omdat hierdoor alle mogelijke combinaties in uitvoer blijven en er
null
is waar de duur niet bestaat voor een bepaald interval. - Gegevens samenvoegen.
count(null)=0
Als u meer tabellen heeft en het algoritme moet worden toegepast op hun unie. Stel dat we drie tabellen hebben tmp1, tmp2, tmp3
allemaal met kolommen tstamp
en duration
. De we kunnen de vorige oplossing uitbreiden:
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
Je moet echt weten with
clausule in PostgreSQL. Het is een waardevol concept voor elke data-analyse in PostgreSQL.