Retrieve aggregates for arbitrary time intervals

房东的猫 提交于 2019-11-30 07:37:46

问题


This is the query I have so far, to create daily bars:

SELECT DISTINCT date_trunc('hour',t) AS date,
min(price) OVER w,
max(price) OVER w,
first_value(price) OVER w,
last_value(price) OVER w
FROM ticker
WINDOW w AS (PARTITION BY date_trunc('hour',t));

Changing 'hour' to 'min' or 'day' would give me the bars corresponding to these units.

However, what if I want 5 min or 15 min bars? date_trunc() doesn't support these and I'm looking for a nice elegant way to do it.


回答1:


For 15-minute intervals, building on your example:

SELECT DISTINCT
     , date_trunc('hour', t) AS h
     , floor(EXTRACT(minute FROM t) / 15) AS m15
     , min(price) OVER w
     , max(price) OVER w
     , first_value(price) OVER w
     , last_value(price) OVER w
FROM   ticker
WINDOW w AS (PARTITION BY date_trunc('hour', t)
                        , floor(extract(minute FROM t) / 15));

Works for 5 minutes, too.


A more generic solution for any regular time intervals, across any period of time:

WITH x AS (
    SELECT t1, t1 + interval '5min' AS t2
    FROM   generate_series(timestamp '2012-07-18 00:00'
                         , timestamp '2012-07-18 23:55'
                         , interval '5 min') AS t1
    )
SELECT DISTINCT ON (1)
       x.t1
     , min(price)         OVER w
     , max(price)         OVER w
     , first_value(price) OVER w
     , last_value(price)  OVER w
FROM   x
JOIN   ticker y ON y.t >= x.t1  -- use LEFT JOIN to include empty intervals
               AND y.t <  x.t2  -- don't use BETWEEN
WINDOW w AS (PARTITION BY x.t1)
ORDER  BY x.t1;

Related answers with more explanation:

  • Best way to count records by arbitrary time intervals in Rails+Postgres
  • Select first row in each GROUP BY group?


来源:https://stackoverflow.com/questions/11533700/retrieve-aggregates-for-arbitrary-time-intervals

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!