【问题标题】:Group OHLC-Stockmarket Data into multiple timeframes - Mysql将 OHLC-Stockmarket 数据分组到多个时间范围 - Mysql
【发布时间】:2012-09-13 06:28:39
【问题描述】:

我需要将具有 {Name, DateTime, Open, High, Low, Close, Volume} 的股票市场“1 分钟”数据分组到不同的时间范围内,即。 MYSQL 上的“5 分钟/15 分钟/60 分钟”。基于 sqlfiddle 构建的架构 - http://sqlfiddle.com/#!2/91433

我找到了一个链接 - Group OHLC-Stockmarket Data into multiple timeframes with T-SQL,对 MSSQL 有类似要求。

我尝试点击链接 - http://briansteffens.com/2011/07/19/row_number-partition-and-over-in-mysql/,获取 row_number(),结束,在 mysql 中进行分区以解决问题。

我是sql新手,谁能指点我正确的方向?

【问题讨论】:

  • 你这里真的有问题吗,或者你只是在陈述你到目前为止所做的事情?
  • @JamWaffles,感谢您对此进行调查。我没有解决这个问题的办法。我想要一个 SQL 查询将“1min”的 ohlc 数据转换为“5min”的间隔。

标签: mysql sql stockquotes group-by


【解决方案1】:

我知道这是一个老问题,但看看这个“更简单”的解决方案。开盘价和收盘价有一个技巧。你可能会喜欢它。

SELECT
  FLOOR(MIN(`timestamp`)/"+period+")*"+period+" AS timestamp,
  SUM(amount) AS volume,
  SUM(price*amount)/sum(amount) AS wavg_price,
  SUBSTRING_INDEX(MIN(CONCAT(`timestamp`, '_', price)), '_', -1) AS `open`,
  MAX(price) AS high,
  MIN(price) AS low,
  SUBSTRING_INDEX(MAX(CONCAT(`timestamp`, '_', price)), '_', -1) AS `close`
FROM transactions_history -- this table has 3 columns (timestamp, amount, price)
GROUP BY FLOOR(`timestamp`/"+period+")
ORDER BY timestamp  

周期以秒为单位

【讨论】:

  • 避免多次查询的好主意!非常感谢
  • period 包含什么?它只是字符串吗?
  • 很久以前了。但是当我现在看它时:它是从外部提供的整数/字符串。查询使用了由“括起来的字符串。Stackoverflow 删除了这些引号。句点与查询字符串的其余部分连接......即从 SQL 的角度来看,它是恒定的。你可以用 300 代替“+period+”,你将有 5 分钟的硬编码.
【解决方案2】:

终于用下面的mysql查询解决了这个问题:

select min(a.mydate),max(a.myhigh) as high,min(a.mylow) as low, 
min(case when rn_asc = 1 then a.myopen end) as open,
min(case when rn_desc = 1 then b.myclose end) as close

from( 

select 
@i := if((@lastdate) != (Floor(unix_timestamp(mydate)/300 )), 1, @i + 1) as rn_asc,
          mydate, myhigh, mylow, myopen, myclose,
          @lastdate := (Floor(unix_timestamp(mydate)/300 ))

from
  onemindata_1,
  (select @i := 0) vt1,
  (select @lastdate := null) vt2 order by mydate

) a

inner join(

select 
@j := if((@lastdate1) != (Floor(unix_timestamp(mydate)/300 )), 1, @j + 1) as rn_desc,
          mydate,myclose,
          @lastdate1 := (Floor(unix_timestamp(mydate)/300 ))

from
  onemindata_1,
  (select @j := 0) vt1,
  (select @lastdate1 := null) vt2 order by mydate desc

)b
on a.mydate=b.mydate
group by (Floor(unix_timestamp(a.mydate)/300 ))

最困难的部分是获得“特定时间间隔”的打开和关闭。我正在对“日期”进行“高、低、开”和“关闭”的内部连接。我可以通过更改 (Floor(unix_timestamp(mydate)/300)) 中的分母来切换时间间隔。目前不担心性能,只要它工作:)。

【讨论】:

    【解决方案3】:

    查询有错误,将收盘价的最小值更改为最大值:

    SELECT
      FLOOR(MIN(`timestamp`)/"+period+")*"+period+" AS timestamp,
      SUM(amount) AS volume,
      SUM(price*amount)/sum(amount) AS wavg_price,
      SUBSTRING_INDEX(MIN(CONCAT(`timestamp`, '_', price)), '_', -1) AS `open`,
      MAX(price) AS high,
      MIN(price) AS low,
      SUBSTRING_INDEX(MAX(CONCAT(`timestamp`, '_', price)), '_', -1) AS `close`
    FROM transactions_history -- this table has 3 columns (timestamp, amount, price)
    GROUP BY FLOOR(`timestamp`/"+period+")
    ORDER BY timestamp  
    

    【讨论】:

      【解决方案4】:

      我发现@Ruslan 的解决方案在最新版本的 MySQL 中不起作用,所以发布一个有效的版本:

      select 
      date_add(str_to_date(date_format(ev.startdatetime, '%Y-%m-%d'),'%Y-%m-%d'), interval 
       hour(ev.startdatetime)*60 + floor(minute(ev.startdatetime)/5)*5 minute) timeframe
       , sum(ev.volume) volume
       , min(ev.startdatetime) mintime
       , substring_index(group_concat(open),',',1) open
       , max(high) as high 
       , min(low) as low
       , substring_index(group_concat(close),',',-1) close
      from es1min_v ev
      group by 
      date_add(str_to_date(date_format(ev.startdatetime, '%Y-%m-%d'),'%Y-%m-%d'), interval 
       hour(ev.startdatetime)*60 + floor(minute(ev.startdatetime)/5)*5 minute) 
      

      【讨论】:

        猜你喜欢
        • 2012-03-09
        • 2021-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-10
        • 1970-01-01
        • 2023-04-07
        相关资源
        最近更新 更多