【问题标题】:Query Database Accurately Based on Timestamp根据时间戳准确查询数据库
【发布时间】:2018-08-16 01:31:05
【问题描述】:

我目前在 Google 大查询数据集中查询价格与时间时遇到了准确性问题。我想要的是每五分钟一个资产的价格,但有些资产有一分钟的空行。

例如,对于两种加密货币 VEN 和 ICX,可能会出现特定秒内的价格数据不可用的时间。在我的查询中,我每 300 秒查询一次数据库并获取价格数据,但有些资产没有 5 分 0 秒的时间戳。因此,我希望获得最后一个已知价格:一个好的价格是 4 分 58 秒。

我现在的查询是:

SELECT MIN(price) AS PRICE, timestamp
FROM [coin_data] 
WHERE coin="BTCUSD" AND TIMESTAMP_TO_SEC(timestamp) % 300 = 0
GROUP BY timestamp
ORDER BY timestamp ASC

此查询会在特定位置产生这种差距:

Row((10339.25, datetime.datetime(2018, 2, 26, 21, 55, tzinfo=<UTC>)))

Row((10354.62, datetime.datetime(2018, 2, 26, 22, 0, tzinfo=<UTC>)))

Row((10320.0, datetime.datetime(2018, 2, 26, 22, 10[should be 5 for 5 min], tzinfo=<UTC>)))

最后一列不应为 10,因为那是分钟位置,应为 5 分钟。

【问题讨论】:

    标签: mysql sql google-bigquery time-series legacy-sql


    【解决方案1】:

    要选择具有 5 分钟标记/时间戳的行(如果存在)或最接近的现有条目,您可以使用 "(analytic) window functions"(使用 OVER())而不是 aggregate functions(使用 GROUP BY) ,如下:

    1. 将所有行分成“单独” 5 分钟组
    2. 按与所需时间的接近程度对它们进行排序
    3. 从每个分区中选择第一行。

    这里我使用OVER 子句创建“窗口框架” 并对其中的行进行排序。然后RANK() 对每个窗口框架中的所有行进行编号。

    标准 SQL

    WITH
      data AS (
      SELECT *,
        CAST(FLOOR(UNIX_SECONDS(timestamp)/300) AS INT64) AS timegroup
      FROM
        `coin_data` )
    SELECT min(price) as min_price, timestamp
    FROM
     (SELECT *, RANK() OVER(PARTITION BY timegroup ORDER BY timestamp ASC) AS rank
      FROM data)
    WHERE rank = 1
    group by timestamp
    ORDER BY timestamp ASC
    

    旧版 SQL

    SELECT MIN(price) AS min_price, timestamp
    FROM (
      SELECT *,
    RANK() OVER(PARTITION BY timegroup ORDER BY timestamp ASC) AS rank,
      FROM (
        SELECT *,
          INTEGER(FLOOR(TIMESTAMP_TO_SEC(timestamp)/300)) AS timegroup
        FROM [coin_data]) AS data )
    WHERE rank = 1
    GROUP BY timestamp
    ORDER BY timestamp ASC
    

    您似乎在同一时间戳有多个价格,在这种情况下,您可能需要在OVER 子句中添加另一个字段。

    OVER(PARTITION BY timegroup, exchange ORDER BY timestamp ASC)
    

    注意事项:

    1. migrating 考虑为标准 SQL,这是用于查询 BigQuery 中存储的数据的首选 SQL 方言。您可以在单个查询的基础上执行此操作,因此您不必同时迁移所有内容。

    2. 我的想法是提供一个通用查询来说明原理,因此我不会过滤空行,因为不清楚它们是 null 还是空字符串,而且对于答案来说并不是必需的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-20
      • 1970-01-01
      • 1970-01-01
      • 2015-04-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-12
      相关资源
      最近更新 更多