Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get a list of dates between two dates

Using standard mysql functions is there a way to write a query that will return a list of days between two dates.

eg given 2009-01-01 and 2009-01-13 it would return a one column table with the values:

 2009-01-01   2009-01-02   2009-01-03  2009-01-04   2009-01-05  2009-01-06  2009-01-07  2009-01-08   2009-01-09  2009-01-10  2009-01-11  2009-01-12  2009-01-13 

Edit: It appears I have not been clear. I want to GENERATE this list. I have values stored in the database (by datetime) but want them to be aggregated on a left outer join to a list of dates as above (I am expecting null from the right side of some of this join for some days and will handle this).

like image 999
Gilgad Avatar asked Feb 04 '09 03:02

Gilgad


People also ask

How can I get a list of dates between two dates?

We can get the dates between two dates with single method call using the dedicated datesUntil method of a LocalDate class. The datesUntill returns the sequentially ordered Stream of dates starting from the date object whose method is called to the date given as method argument.

How do I get all dates between start and end date?

To get all of the dates between 2 dates: Copied! function getDatesInRange(startDate, endDate) { const date = new Date(startDate. getTime()); const dates = []; while (date <= endDate) { dates.


1 Answers

I would use this stored procedure to generate the intervals you need into the temp table named time_intervals, then JOIN and aggregate your data table with the temp time_intervals table.

The procedure can generate intervals of all the different types you see specified in it:

call make_intervals('2009-01-01 00:00:00','2009-01-10 00:00:00',1,'DAY') . select * from time_intervals   . interval_start      interval_end         ------------------- -------------------  2009-01-01 00:00:00 2009-01-01 23:59:59  2009-01-02 00:00:00 2009-01-02 23:59:59  2009-01-03 00:00:00 2009-01-03 23:59:59  2009-01-04 00:00:00 2009-01-04 23:59:59  2009-01-05 00:00:00 2009-01-05 23:59:59  2009-01-06 00:00:00 2009-01-06 23:59:59  2009-01-07 00:00:00 2009-01-07 23:59:59  2009-01-08 00:00:00 2009-01-08 23:59:59  2009-01-09 00:00:00 2009-01-09 23:59:59  . call make_intervals('2009-01-01 00:00:00','2009-01-01 02:00:00',10,'MINUTE') .  select * from time_intervals .   interval_start      interval_end         ------------------- -------------------  2009-01-01 00:00:00 2009-01-01 00:09:59  2009-01-01 00:10:00 2009-01-01 00:19:59  2009-01-01 00:20:00 2009-01-01 00:29:59  2009-01-01 00:30:00 2009-01-01 00:39:59  2009-01-01 00:40:00 2009-01-01 00:49:59  2009-01-01 00:50:00 2009-01-01 00:59:59  2009-01-01 01:00:00 2009-01-01 01:09:59  2009-01-01 01:10:00 2009-01-01 01:19:59  2009-01-01 01:20:00 2009-01-01 01:29:59  2009-01-01 01:30:00 2009-01-01 01:39:59  2009-01-01 01:40:00 2009-01-01 01:49:59  2009-01-01 01:50:00 2009-01-01 01:59:59  . I specified an interval_start and interval_end so you can aggregate the  data timestamps with a "between interval_start and interval_end" type of JOIN. . Code for the proc: . -- drop procedure make_intervals . 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; 

Similar example data scenario at the bottom of this post, where I built a similar function for SQL Server.

like image 83
Ron Savage Avatar answered Oct 23 '22 19:10

Ron Savage