3

my_valuesデータベースよりも時間軸の解像度を低くしてプロットしたいと考えています。次のような SQL を使用して、時間間隔 (たとえば 1 時間) ごとの平均値を取得します。

SELECT DATE_TRUNC('hour', my_timestamps) AS my_time_lowres
     , AVG(my_values) 
FROM my_table 
GROUP BY my_time_lowres

それを使用date_trunc()すると、タイムスタンプの解像度をある程度減らすことができます(docsによると):

select date_trunc('hour', timestamp '2001-02-16 20:38:40') 
-- the output is: 2001-02-16 20:00:00

このようにして、次の間隔サイズ (およびいくつかの大きい/小さいサイズ) に対してこれを行うことができます。

...
second
minute
hour
day
week
...

3時間、6時間など、他の時間間隔でもこれを達成する方法はありますか?

4

2 に答える 2

6

このデモを検討して、タイムスタンプを 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 デモがあります。

于 2012-10-04T16:34:03.933 に答える
0

エポックからの秒数に変換し、3*3600、6*3600 などで整数除算することができます。

于 2012-10-04T14:57:28.610 に答える