このデモを検討して、タイムスタンプを 15 分の解像度に下げ、結果の重複を集計します。
WITH tbl(id, ts) AS ( VALUES
(1::int, '2012-10-04 00:00:00'::timestamp)
,(2, '2012-10-04 18:23:01')
,(3, '2012-10-04 18:30:00')
,(4, '2012-10-04 18:52:33')
,(5, '2012-10-04 18:55:01')
,(6, '2012-10-04 18:59:59')
,(7, '2012-10-05 11:01:01')
)
SELECT to_timestamp((extract(epoch FROM ts)::bigint / 900)*900)::timestamp
AS lower_bound
, to_timestamp(avg(extract(epoch FROM ts)))::timestamp AS avg_ts
, count(*) AS ct
FROM tbl
GROUP BY 1
ORDER BY 1;
結果:
lower_bound | avg_ts | ct
---------------------+---------------------+----
2012-10-04 00:00:00 | 2012-10-04 00:00:00 | 1
2012-10-04 18:15:00 | 2012-10-04 18:23:01 | 1
2012-10-04 18:30:00 | 2012-10-04 18:30:00 | 1
2012-10-04 18:45:00 | 2012-10-04 18:55:51 | 3
2012-10-05 11:00:00 | 2012-10-05 11:01:01 | 1
トリックは、@Michael が既に投稿したような UNIX エポックを抽出することです。小数桁が切り捨てられるため、整数除算では、選択した解像度のバケットにそれらがまとめられます。
15 分 = 900 秒なので、900 で割ります。
結果を取得するには、同じ数を掛けlower_bound
ます。を使用して、UNIX エポックをタイムスタンプに変換しto_timestamp()
ます。
これは、10 進法で小数桁なしで表すことができる間隔に最適です。さらに汎用性を高めるwidth_bucket()
には、この最近の密接に関連する回答で示したように、見過ごされがちな関数を使用します。詳細な説明、リンク、および sqlfiddle デモがあります。