问题
I have a MySQL database in which I write data every 10 minutes. i.e.:
+---------------------+
| datetime |
+---------------------+
| 2018-09-03 13:01:49 |
| 2018-09-03 12:51:49 |
| 2018-09-03 12:41:49 |
+---------------------+
In my Python code I want to get just rows which are "exactly" n-hour old, i.e.:
+---------------------+
| 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 |
+---------------------+
I have this code which returns data I want:
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()
And here comes my question: If I will reboot the system, or there will be some problem or delay, and minutes in datetime of last record and records before the last one will not corresponding, I will get empty reply from database (because query ... LIKE "22"
not match with query ... LIKE "21"
).
So, what is the best way to get data from the database with some tolerance (let's say +- 4,99 min)?
回答1:
If you write your data approximately every 10 minutes, it means that you want to fetch every 6th row, when you order by datetime
.
You could try this:
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
This is alternative approach, it will calculate how close datetime is to be"full hour" away from your latest date and it will filter based on that (it allows times to vary by 5 minutes):
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
回答2:
Assuming you want the records around the last record time, you should try to look for time differences between the last recorded time, something like
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
回答3:
Let say u need only data 1-hour or less old and datetime is your column name.
select * from temperatures where TIMESTAMPDIFF(HOUR, datetime, NOW()) <= 1 ;
来源:https://stackoverflow.com/questions/52149257/get-every-n-hour-data-from-database-with-tolerance