迅速で汚い方法: http://sqlfiddle.com/#!1/bd2f6/21 列にtstamp
という名前を付けました 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
簡単な説明:
- 最小タイムスタンプと最大タイムスタンプを計算する
- 最小値と最大値の間に15分間隔を生成します
- 期間の一意の値を持つクロス結合の結果
- 元のデータを左結合します(左結合は重要です。これにより、可能なすべての組み合わせが出力に保持され、
null
が存在するためです。 指定された間隔で期間が存在しない場合。 - データを集約します。
count(null)=0
より多くのテーブルがあり、アルゴリズムをそれらの和集合に適用する必要がある場合。 3つのテーブルtmp1, tmp2, tmp3
があるとします。 すべて列tstamp
およびduration
。以前のソリューションを拡張できます:
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
with
を本当に知っておく必要があります PostgreSQLの句。これは、PostgreSQLでのデータ分析にとって非常に貴重な概念です。