7

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

我找到了一个链接 -使用 T-SQL 将 OHLC-Stockmarket 数据分组到多个时间范围内,对 MSSQL 有类似的要求。

我试图按照链接 - http://briansteffens.com/2011/07/19/row_number-partition-and-over-in-mysql/,在mysql中获取row_number(),over,partition来解决问题。

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

4

4 回答 4

15

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

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  

周期以秒为单位

于 2013-11-15T09:09:41.293 回答
1

最后用下面的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)) 中的分母来切换时间间隔。目前不担心性能,只要它有效:)。

于 2012-09-21T18:28:07.180 回答
0

查询有错误,将收盘价的 MIN 更改为 MAX:

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  
于 2015-08-12T09:10:53.263 回答
0

我发现@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) 
于 2020-06-30T14:22:34.563 回答