Truncate timestamp to arbitrary intervals

后端 未结 2 1900
渐次进展
渐次进展 2020-12-21 09:43

I want to plot my_values with some lower resolution on the time axis than I have in the database. I use something like the following SQL to get the average valu

相关标签:
2条回答
  • 2020-12-21 10:34

    You can convert to the number of seconds since epoch and go for integer division by 3*3600, 6*3600, etc.

    0 讨论(0)
  • 2020-12-21 10:39

    Consider this demo to bring timestamps down to a resolution of 15 minutes and aggregate resulting dupes:

    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;
    

    Result:

         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
    

    The trick is to extract a unix epoch like @Michael already posted. Integer division lumps them together in buckets of the chosen resolution, because fractional digits are truncated.

    I divide by 900, because 15 minutes = 900 seconds.

    Multiply by the same number to get the resulting lower_bound. Convert the unix epoch back to a timestamp with to_timestamp().

    This works great for intervals that can be represented without fractional digits in the decimal system. For even more versatility use the often overlooked function width_bucket() like I demonstrate in this recent, closely related answer. More explanation, links and an sqlfiddle demo over there.

    0 讨论(0)
提交回复
热议问题