从数据库中获取每 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
我有一个 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