重要なのは、結果セットを結合するための仮想テーブルを作成することです。このgenerate_series
関数は、次の方法でそれを行うのに役立ちます。
SELECT
start
, start + interval '8 hours' as end
FROM (
SELECT generate_series(
date'2012-01-01'
, date'2012-02-02'
, '1 hour'
) AS start
) x;
これにより、次のような出力が生成されます。
start | end
------------------------+------------------------
2012-01-01 00:00:00+00 | 2012-01-01 08:00:00+00
2012-01-01 01:00:00+00 | 2012-01-01 09:00:00+00
2012-01-01 02:00:00+00 | 2012-01-01 10:00:00+00
2012-01-01 03:00:00+00 | 2012-01-01 11:00:00+00
これにより、データを結合するための何かが得られます。このようにして、次のクエリを実行します。
SELECT
y.start
, round(avg(ts_val.v))
FROM
ts_val,
(
SELECT
start
, start + interval '8 hours' as end
FROM (
SELECT generate_series(
date'2012-01-01'
, date'2012-02-02'
, '1 hour'
) AS start
) x
) y
WHERE
ts BETWEEN y.start AND y.end
GROUP BY
y.start
ORDER BY
y.start
;
以下のデータについて
ts | v
---------------------+---
2012-01-01 01:00:00 | 2
2012-01-01 09:00:00 | 2
2012-01-01 10:00:00 | 5
(3 rows)
次の結果が生成されます。
start | round
------------------------+-------
2012-01-01 00:00:00+00 | 2.0
2012-01-01 01:00:00+00 | 2.0
2012-01-01 02:00:00+00 | 3.5
2012-01-01 03:00:00+00 | 3.5
2012-01-01 04:00:00+00 | 3.5
2012-01-01 05:00:00+00 | 3.5
2012-01-01 06:00:00+00 | 3.5
2012-01-01 07:00:00+00 | 3.5
2012-01-01 08:00:00+00 | 3.5
2012-01-01 09:00:00+00 | 3.5
2012-01-01 10:00:00+00 | 5.0
(11 rows)