【问题标题】:Given time/interval to calculate open/high/low/close value in each grouped data给定时间/间隔来计算每个分组数据中的开/高/低/收值
【发布时间】:2015-02-08 12:46:23
【问题描述】:

假设原始数据是:

  Timestamp   High Low Volume
  10:24.22345 100   99  10
  10:24.23345 110   97  20
  10:24.33455 97    89  40
  10:25.33455 60    40  50
  10:25.93455 40    20  60

采样时间为 1 秒,输出数据应如下(按秒分组):

  Timestamp   Open Close High  Low Volume 
  10:24         82   83   110   89  70     
  10:25         50   40   60    20  110    
  • Open 表示组内最早数据的价格
  • Close表示组内最新数据的价格
  • Volume 表示组中的总和(音量)

采样单元来自1 second, 5 sec, 1 minute, 1 hour, 1 day, ...

现在我可以通过以下 SQL 获取 High、Low、Volume:

SELECT date_trunc(\'#{interval}\', ticktime) AS ticktime_stamp,
       max(bid_price) as high,
       min(bid_price) as low,
       sum(bid_volume) as volume,
       max(product_type) as product_type
FROM   czces
WHERE  ticktime >=  \'#{begin_time}\'::timestamp
AND  ticktime <  \'#{end_time}\'::timestamp
AND  product_type =\'#{product_type}\'
GROUP  BY 1
ORDER  BY ticktime_stamp ASC

但是如何根据上面的查询得到每个组中的openclose值呢?

【问题讨论】:

  • 您的原始数据没有价格,OpenClose 的数字不匹配。你能做到一致吗?
  • 你能添加一个带有实际表和一些数据的 SQLFiddle 吗?我真的不明白你在 Open 上是如何拥有 82 的,因为这不在数据中。

标签: sql postgresql aggregate-functions window-functions


【解决方案1】:

您可以使用 window functionsDISTINCT ON 来实现:

SELECT DISTINCT ON (1)
       date_trunc('#{interval}', ticktime) AS ticktime_stamp
     , max(bid_price)         OVER w AS high
     , min(bid_price)         OVER w AS low
     , sum(bid_volume)        OVER w AS volume
     , max(product_type)      OVER w AS product_type
     , min(product_type)      OVER w AS product_type
     , first_value(bid_price) OVER w AS open
     , last_value(bid_price)  OVER w AS close
FROM   czces
WHERE  ticktime >= '#{begin_time}'::timestamp
AND    ticktime <  '#{end_time}'::timestamp
AND    product_type ='#{product_type}'
WINDOW w AS (PARTITION BY date_trunc('#{interval}', ticktime) ORDER BY ticktime
             ROWS BETWEEN UNBOUNDED PRECEDING
                      AND UNBOUNDED FOLLOWING)
ORDER  BY 1;

自定义窗框说明:

DISTINCT ON的解释:

【讨论】:

    【解决方案2】:

    您要查找的查询很可能是这个,但没有实际的测试数据很难确定。

    SELECT
      min(date_trunc('second', "Timestamp")) OVER minutes "Timestamp",
      first_value("Price") OVER minutes "Open",
      last_value("Price") OVER minutes "Close",
      max("High") OVER minutes "High",
      min("Low") OVER minutes "Low",
      sum("Volume") OVER minutes "Volume"
    FROM czces
    WINDOW minutes AS (
        PARTITION BY date_trunc('second', "Timestamp")
        ORDER BY "Timestamp"
    );
    

    【讨论】:

      猜你喜欢
      • 2022-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-17
      • 1970-01-01
      • 1970-01-01
      • 2020-09-20
      • 1970-01-01
      相关资源
      最近更新 更多