最后插入记录的时间间隔分组
Posted
技术标签:
【中文标题】最后插入记录的时间间隔分组【英文标题】:Group on time interval on last inserted records 【发布时间】:2017-09-20 08:59:03 【问题描述】:我得到了一个如下所示的数据集:
localDateTime |bid
--------------------|--------
2017-09-17 15:35:05 |3085
2017-09-17 15:35:54 |3100
2017-09-17 15:37:05 |3100.2
2017-09-17 15:38:06 |3101.6
etc..
我想按时间字段对其进行分组,并获取每个时间间隔的 MAX(openBid) 并拥有最后 5 个间隔(在本例中为 5 分钟)。我使用这个查询:
SELECT
MIN(localDateTime) startTime
,MAX(bid) maxOpenBid
,COUNT(*) countRecords
FROM
Ticker
GROUP BY
UNIX_TIMESTAMP(localDateTime) DIV 300
ORDER BY ID DESC
LIMIT 5
这给出了以下结果:
startTime |maxOpenBid |countRecords
--------------------|-----------|------------
2017-09-20 10:50:03 |3306.9 |3
2017-09-20 10:45:03 |3305 |5
2017-09-20 10:40:04 |3304.9 |5
2017-09-20 10:35:04 |3306 |5
2017-09-20 10:30:03 |3303.2 |5
我遇到的问题是结果集中第一条记录的计数随着时间的推移从 1 增加到 5。在此示例中为 3。我希望我的查询在所有时间间隔内具有相同数量的记录。我认为问题在于 GROUP BY 准时从集合的第一条记录开始。由于我正在执行 ORDER BY DESC,因此我希望它从集合的最后一条记录开始。
【问题讨论】:
如果我正确理解您的问题 - 我个人的做法是忘记使用时间戳(除了您现有的问题,由于服务停机等原因可能会丢失条目)并切换到连续的自动递增数字。如果您感到懒惰,可以使用自动递增的主键(前提是您的服务器设置为精确地增加 1 - mysql 集群会破坏这种方法),您可以这样做GROUP BY FLOOR(pk_column / 5)
按照我的方法,您可能必须提供一个偏移量来“纠正”第一条记录......例如GROUP BY FLOOR((pk_column + 4) / 5)
没想到,很好的建议,谢谢!
不幸的是,这仍然会产生同样的问题。它从记录 1 开始计数,而不是从最后一条记录开始计数。所以我最后插入的记录仍然不完整。
您可能需要从 1. 5/5 = 1 开始抵消它,因此您只会在第一组中获得 4 个(假设您从 1 开始...除以5 层到 0)。尝试将 pk 字段偏移 +4(和/或在遇到困难时分享您的方案和数据)
【参考方案1】:
找到了解决方案,@wally 让我朝着正确的方向前进。
这是我为使其工作所做的工作:
SET @rownr =-1;
SELECT
MIN(localDateTime) startTime
,MAX(bid) maxOpenBid
,COUNT(*) countRecords
FROM
(
SELECT
(@rownr := (@rownr+1)) rownr
,ID
,localDateTime
,bid openBid
,ask openAsk
FROM
Ticker
ORDER BY ID DESC
LIMIT 25
) Ticker
GROUP BY
FLOOR(rownr/5)
ORDER BY ID DESC
LIMIT 5
通过生成按 PK 排序的子集,使用“Ticker”的子查询也对性能产生了非常大的影响。
【讨论】:
以上是关于最后插入记录的时间间隔分组的主要内容,如果未能解决你的问题,请参考以下文章
sql 分组查询time时间间隔大于30分钟的两行,列出2条记录,并列出每组首尾记录,求大神解决!
将 DateTime 分组为 5、15、30 和 60 分钟间隔