从数据库中获取每 n 小时的数据并具有容差

Get every n-hour data from database with tolerance

我有一个 MySQL 数据库,我每 10 分钟向其中写入一次数据。即:

+---------------------+
| datetime            |
+---------------------+
| 2018-09-03 13:01:49 |
| 2018-09-03 12:51:49 |
| 2018-09-03 12:41:49 |
+---------------------+

在我的 Python 代码中,我只想获取 "exactly" n 小时前的行,即:

+---------------------+
| datetime            |
+---------------------+
| 2018-09-03 13:01:49 |
| 2018-09-03 12:01:49 |
| 2018-09-03 11:01:49 |
| 2018-09-03 10:01:49 |
| 2018-09-03 09:01:49 |
| 2018-09-03 08:01:49 |
+---------------------+

我有这段代码 returns 我想要的数据:

cursor.execute('SELECT max(datetime) FROM temperatures')
last_record_datetime = cursor.fetchone()
last_record_min = last_record_datetime[0].minute

query = f'SELECT * FROM temperatures WHERE DATETIME LIKE "%:%{last_record_min}:%" ORDER BY ID DESC LIMIT 20'
cursor.execute(query)
query_result = cursor.fetchall()

我的问题来了:如果我重新启动系统,或者会有一些问题或延迟,最后一条记录的日期时间分钟和最后一条之前的记录不对应,我会得到空回复数据库(因为查询 ... LIKE "22" 与查询 ... LIKE "21" 不匹配)。

那么,从数据库中获取具有一定公差(比如 +- 4.99 分钟)的数据的最佳方法是什么?

如果您大约每 10 分钟写入一次数据,这意味着当您按 datetime 排序时,您希望每 6 行获取一次。

你可以试试这个:

select @rn := 1;

select `datetime` from (
    select @rn := @rn + 1 rn, `datetime` from temperatures
    order by `datetime` desc
) where mod(rn, 6) = 1
--limit 20

这是另一种方法,它将计算日期时间与您的最新日期的距离"full hour" 有多近,并且将基于此进行过滤(允许时间相差 5 分钟):

select @dt := max(`datetime`) from temperatures;

select * from (
    select `datetime`, 
           mod(abs(timestampdiff(minuite,@dt,`datetime`)), 60) minDiff
    from temperatures
) a where minDiff < 5 or minDiff > 55
--limit 20

假设您只需要 1 小时或更早的数据,并且日期时间是您的列名。

select * from temperatures where TIMESTAMPDIFF(HOUR, datetime, NOW()) <= 1 ; 

假设你想要上次记录时间前后的记录,你应该尝试寻找上次记录时间之间的时差,比如

SELECT * FROM temperatures WHERE DATETIME BETWEEN DATE_SUB({last_record_min}, INTERVAL 5 MINUTE) AND DATE_ADD({last_record_min}, INTERVAL 5 MINUTE) ORDER BY ID DESC LIMIT 20