Rychlý a špinavý způsob:http://sqlfiddle.com/#!1/bd2f6/21 Svůj sloupec jsem pojmenoval tstamp
místo vašeho 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
Stručné vysvětlení:
- Vypočítejte minimální a maximální časové razítko
- Vygenerujte 15minutové intervaly mezi minimem a maximem
- Výsledky křížového spojení s jedinečnými hodnotami trvání
- Původní data levého spojení (levé spojení je důležité, protože ve výstupu zůstanou všechny možné kombinace a bude zde
null
kde trvání pro daný interval neexistuje. - Souhrnná data.
count(null)=0
V případě, že máte více tabulek a algoritmus by měl být aplikován na jejich sjednocení. Předpokládejme, že máme tři tabulky tmp1, tmp2, tmp3
vše se sloupci tstamp
a duration
. Předchozí řešení můžeme rozšířit:
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
Měli byste opravdu znát with
klauzule v PostgreSQL. Je to neocenitelný koncept pro jakoukoli analýzu dat v PostgreSQL.