Each row in my table has a date time stamp, and I wish to query the database from now, to count how many rows are in the last 30 days, the 30 days before that and so on. Until there is a 30 day bin going back to the start of the table.
I have successfully carried out this query by using Python and making several queries. But I’m almost certain that it can be done in one single MySQL query.
No stored procedures, temporary tables, only one query, and an efficient execution plan given an index on the date column:
It should be pretty obvious what is happening here, except for this incantation:
That expression appears several times, and it evaluates to the number of 30-day periods ago
dateStampColumnis.dateDiffreturns the difference in days, divide it by 30 to get it in 30-day periods, and feed it all tofloor()to round it to an integer. Once we have this number, we canGROUP BYit, and further we do a bit of math to translate this number back into the starting and ending dates of the period.Replace
'2012-12-31'withnow()if you prefer. Here’s some sample data:And the result:
period endpoints are inclusive.
Play with this in SQL Fiddle.
There’s a bit of potential goofiness in that any 30 day period with zero matching rows will not be included in the result. If you could join this against a table of periods, that could be eliminated. However, MySQL doesn’t have anything like PostgreSQL’s generate_series(), so you’d have to deal with it in your application or try this clever hack.