在Google Big Query数据集中查询价格与时间时,我目前遇到准确性问题。我想要的是每五分钟一次资产的价格,但是有些资产在一分钟内有一个空行。
例如,对于两个加密货币的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分钟。
答案 0 :(得分:0)
要选择具有5分钟标记/时间戳(如果存在)或最近的现有条目的行,您可以使用"(analytic) window functions"(使用OVER()
)代替aggregate functions (使用GROUP BY
),如下所示:
这里我使用OVER
子句创建&#34;窗口框架&#34; 并对其中的行进行排序。然后RANK()
对每个窗口框架中的所有行进行编号。
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
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)
考虑migrating到标准SQL ,这是用于查询存储在BigQuery中的数据的首选 SQL方言。您可以在单个查询的基础上执行此操作,因此您不必同时迁移所有内容。
我的想法是提供一个通用查询来说明原理,因此我不会过滤空行,因为它不清楚它们是空的还是空字符串而且它是&#39 ;答案不是真的必要。