Full credit to Ron Savage over at Stack Exchange. He's written this fantastic function which creates a temporary table with two columns, 'interval_start' and 'interval_end'.
You call this function with a MySQL datetime ('2011-02-23 05:00:00'), and a MySQL end datetime ('2011-02-23 16:00:00'). You then specify what you want returned back to you (Seconds, Minutes, Hours, Days etc. See the function below for the full list of options).
What is returned is below will be similar;
interval_start | interval_end |
---|---|
2011-02-23 05:00:00 | 2011-02-23 05:59:59 |
2011-02-23 06:00:00 | 2011-02-23 06:59:59 |
2011-02-23 07:00:00 | 2011-02-23 07:59:59 |
2011-02-23 08:00:00 | 2011-02-23 08:59:59 |
2011-02-23 09:00:00 | 2011-02-23 09:59:59 |
2011-02-23 10:00:00 | 2011-02-23 10:59:59 |
2011-02-23 11:00:00 | 2011-02-23 11:59:59 |
2011-02-23 12:00:00 | 2011-02-23 12:59:59 |
2011-02-23 13:00:00 | 2011-02-23 13:59:59 |
2011-02-23 14:00:00 | 2011-02-23 14:59:59 |
2011-02-23 15:00:00 | 2011-02-23 15:59:59 |
And his fantastic function is below!
DELIMITER //; CREATE PROCEDURE make_intervals(startdate timestamp, enddate timestamp, intval integer, unitval varchar(10)) BEGIN -- ************************************************************************* -- Procedure: make_intervals() -- Author: Ron Savage -- Date: 02/03/2009 -- -- Description: -- This procedure creates a temporary table named time_intervals with the -- interval_start and interval_end fields specifed from the startdate and -- enddate arguments, at intervals of intval (unitval) size. -- ************************************************************************* declare thisDate timestamp; declare nextDate timestamp; set thisDate = startdate; -- ************************************************************************* -- Drop / create the temp table -- ************************************************************************* drop temporary table if exists time_intervals; create temporary table if not exists time_intervals ( interval_start timestamp, interval_end timestamp ); -- ************************************************************************* -- Loop through the startdate adding each intval interval until enddate -- ************************************************************************* repeat select case unitval when 'MICROSECOND' then timestampadd(MICROSECOND, intval, thisDate) when 'SECOND' then timestampadd(SECOND, intval, thisDate) when 'MINUTE' then timestampadd(MINUTE, intval, thisDate) when 'HOUR' then timestampadd(HOUR, intval, thisDate) when 'DAY' then timestampadd(DAY, intval, thisDate) when 'WEEK' then timestampadd(WEEK, intval, thisDate) when 'MONTH' then timestampadd(MONTH, intval, thisDate) when 'QUARTER' then timestampadd(QUARTER, intval, thisDate) when 'YEAR' then timestampadd(YEAR, intval, thisDate) end into nextDate; insert into time_intervals select thisDate, timestampadd(MICROSECOND, -1, nextDate); set thisDate = nextDate; until thisDate >= enddate end repeat; END//
So to run the query, you'd basically call it with the following
CALL make_intervals(('2011-02-23 10:00:00' - INTERVAL 5 HOUR),('2011-02-23 10:00:00' + INTERVAL 6 HOUR),1,'HOUR'); SELECT * FROM time_intervals;
So why would you do this? Depending on what you're working with, you could start to produce results for a month worth of sales for example, but rather than have program fill in the blanks for all the days that are missing and have no sales, join the sales (and allow NULL or 0 results from these sales) to this temporary table.
In my use for a mate's horrible exercise, the data he was using was simply... "holely", and while we weren't in a position to fix the data we had, using this simply allowed us to pull in available data using LEFT JOIN and allowing NULLS to be returned to us.
It's far easier to have MySQL do the leg work for you, rather than to gather the data that is available (in 18 MySQL statements...) and walk through your array of results, moving only onto the next index of the array when you find acceptable data. Which needless to say, was incredibly bulky in terms of PHP, ugly and what I would define as unmanageable!
So in conclusion! Huge thanks to Ron, this function in my opinion is extremely useful, and I hope others find it as useful as I have
I use this script. but i am getting error. Please help me out.
the error is:
#1064 – You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ” at line 13
Is There any consequences using temporary table with many client will call these procedure???
No idea. I haven’t done any benchmarking for it. But in the case where we needed to use this, we weren’t left with any other alternative to generate the data we required without “looping” through data on PHP’s side. Which I’m almost positive would have been slower in each call.
Many headaches were saved thanks to this.
True story. Many lives were saved as well. The lives of those in charge of entering data but failing hard >_>