【问题标题】:Selecting Candlestick data (max, min, open, close) for specific period of time选择特定时间段的烛台数据(最大值、最小值、开盘价、收盘价)
【发布时间】:2018-04-04 13:43:55
【问题描述】:

我正在处理烛台图表数据。我有一个数据库表(MySql)与

created                  value
2017-09-25 17:55:04    3322.09
2017-09-25 18:00:03    3317.49
2017-09-25 18:05:02    3316.12
2017-09-25 18:10:03    3325.16
2017-09-25 18:15:04    3326.01
2017-09-25 18:20:03    3330.49
2017-09-25 18:25:04    3331.49
2017-09-25 18:30:04    3335.24
2017-09-25 18:35:03    3347.13
2017-09-25 18:40:03    3343.21
2017-09-25 18:45:05    3341.78
2017-09-25 18:50:03    3339.64
2017-09-25 18:55:04    3336.12
2017-09-25 19:00:04    3327.73
2017-09-25 19:05:03    3327.96
2017-09-25 19:10:04    3325.93

我正在尝试为任何时间段(例如 15 分钟或每 4 小时、每 6 天等)选择最大值、最小值、打开值、关闭值

到现在为止

SELECT p.created, HOUR(`DATE`), MAX(p.value), MIN(p.value) 
FROM price 
GROUP BY DATE(`DATE`),HOUR(`DATE`)

没那么复杂。它给了我每小时的最大值和最小值,所以对于分钟和“完整”时间段,如天、周、月,我可以使用 MONTH、DAY 等函数。

知道如何为任何时间段(比如 28 分钟或 31 小时等)构建查询吗?此外,这适用于最大值和最小值,但我还需要时间段的开盘值(第一个)和收盘值(最后一个)。

【问题讨论】:

  • 查看stackoverflow.com/questions/7745609/…了解如何获取时间段的开盘和收盘值。
  • 要获取特定时间段,请使用WHERE created BETWEEN start_time AND end_time
  • @Barmar - 不,请不要使用BETWEEN。特别是当时间戳具有亚秒级精度时,最好使用独占上限 (<),以免发生意外情况。
  • @Jakub - 我通常喜欢构建一个临时/虚拟表(通常只是一个内联引用)的分组范围。这对于日历表和数字表来说是最简单的,但我们的想法是获得类似 (groupId=1, start='2014-01-01 00:00:00.000', end=start + 28 minutes) 的内容,然后您可以对其进行分组,并且通常也有助于点击索引。

标签: mysql sql charts


【解决方案1】:

要对任意时间段进行分组,您可以将created 列的 UNIX 时间值(即自 UNIX 纪元以来的秒数)除以所需时间段的大小,仅取整数部分结果商的(并丢弃余数)。所以,每 28 分钟分组一次:

SELECT   FROM_UNIXTIME(28*60 * (UNIX_TIMESTAMP(created) DIV (28*60))) grp_id
         MIN(value)    min_value,
         MAX(value)    max_value,
         MIN(created)  min_created,
         MAX(created)  max_created
FROM     price
GROUP BY grp_id

您会注意到,我还选择了min_createdmax_created,它们会产生每组中第一个和最后一个值的时间。然后您可以再次将结果连接回price表以获得相关记录的values(这本质上是“groupwise maximum/minimum”问题的一个实例):

SELECT t.grp_id,
       t.min_value,
       t.max_value,
       price_min.value first_value,
       price_max.value last_value
FROM (
  SELECT   FROM_UNIXTIME(28*60 * (UNIX_TIMESTAMP(created) DIV (28*60))) grp_id
           MIN(value)    min_value,
           MAX(value)    max_value,
           MIN(created)  min_created,
           MAX(created)  max_created
  FROM     price
  GROUP BY grp_id
) t JOIN price price_min ON price_min.created = t.min_created
    JOIN price price_max ON price_max.created = t.max_created

sqlfiddle 上查看。

【讨论】:

  • :winces: 哎哟。没有给你的索引,回来,一年。
  • @Clockwork-Muse:取决于数据集的大小。如果需要,请务必将grp_id 缓存在索引列中。
  • 什么?不。那将假设这些组是稳定的,我倾向于认为这不太可能(至少已经提到了两个)。我更愿意解决获得可连接、可索引标准的一般问题。
  • @Clockwork-Muse:我期待看到您提出的解决方案。
  • 如果表“price”包含 2 个或更多具有相同日期(创建)的记录,则此 SQL 可能返回 2 个或更多具有相同“grp_id”的记录(因为连接)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-05
  • 1970-01-01
  • 2022-12-04
  • 1970-01-01
  • 2020-02-23
相关资源
最近更新 更多