Select rows that are less than 5 minutes old using DATE_SUB

17,681

Solution 1

You don't really need DATE_ADD/DATE_SUB, date arithmetic is much simpler:

SELECT COUNT(id), DATE_FORMAT(`timestamp`, '%Y-%m-%d %H:%i')
FROM `table`
WHERE `timestamp` >= CURRENT_TIMESTAMP - INTERVAL 5 MINUTE
GROUP BY 2
ORDER BY 2

Solution 2

The following seems like it would work which is mighty close to what you had:

SELECT 
  MINUTE(date_field) as `minute`,
  count(id) as count
FROM table 
WHERE date_field > date_sub(now(), interval 5 minute)
GROUP BY MINUTE(date_field)
ORDER BY MINUTE(date_field);

Note the added column to show the minute and the GROUP BY clause that gathers up the results into the corresponding minute. Imagine that you had 5 little buckets labeled with the last 5 minutes. Now imagine you tossed each row that was 4 minutes old into it's own bucket. count() will then count the number of entries found in each bucket. That's a quick visualization on how GROUP BY works. http://www.tizag.com/mysqlTutorial/mysqlgroupby.php seems to be a decent writeup on GROUP BY if you need more info.

If you run that and the number of entries in each minute seems too high, you'll want to do some troubleshooting. Try replacing COUNT(id) with MAX(date_field) and MIN(date_field) so you can get an idea what kind of dates it is capturing. If MIN() and MAX() are inside the range, you may have more data written to your database than you realize.

You might also double check that you don't have dates in the future as they would all be > now(). The MIN()/MAX() checks mentioned above should identify that too if it's a problem.

Share:
17,681
Tom Sampson
Author by

Tom Sampson

Updated on June 05, 2022

Comments

  • Tom Sampson
    Tom Sampson almost 2 years

    I have a table that is getting hundreds of requests per minute. The issue that I'm having is that I need a way to select only the rows that have been inserted in the past 5 minutes. I am trying this:

    SELECT count(id) as count, field1, field2
    FROM table
    WHERE timestamp > DATE_SUB(NOW(), INTERVAL 5 MINUTE)
    ORDER BY timestamp DESC
    

    My issue is that it returns 70k+ results and counting. I am not sure what it is that I am doing wrong, but I would love to get some help on this. In addition, if there were a way to group them by minute to have it look like:

    | count | field1 | field2 | 
    ----------------------------
    

    I'd love the help and direction on this, so please let me know your thoughts.