Get a list of dates between two dates

后端 未结 20 2122
醉梦人生
醉梦人生 2020-11-22 00:26

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

相关标签:
20条回答
  • 2020-11-22 00:48

    Well how to find dates between two given date in SQL server is explain on http://ektaraval.blogspot.com/2010/09/writing-recursive-query-to-find-out-all.html

    0 讨论(0)
  • 2020-11-22 00:49

    You can use MySQL's user variables like this:

    SET @num = -1;
    SELECT DATE_ADD( '2009-01-01', interval @num := @num+1 day) AS date_sequence, 
    your_table.* FROM your_table
    WHERE your_table.other_column IS NOT NULL
    HAVING DATE_ADD('2009-01-01', interval @num day) <= '2009-01-13'
    

    @num is -1 because you add to it the first time you use it. Also, you can't use "HAVING date_sequence" because that makes the user variable increment twice for each row.

    0 讨论(0)
  • 2020-11-22 00:50

    We used this in our HRMS System you will find it useful

    SELECT CAST(DAYNAME(daydate) as CHAR) as dayname,daydate
        FROM
        (select CAST((date_add('20110101', interval H.i*100 + T.i*10 + U.i day) )as DATE) as daydate
          from erp_integers as H
        cross
          join erp_integers as T
        cross
          join erp_integers as U
         where date_add('20110101', interval H.i*100 + T.i*10 + U.i day ) <= '20110228'
        order
            by daydate ASC
            )Days
    
    0 讨论(0)
  • 2020-11-22 00:51

    For MSSQL you can use this. It is VERY quick.

    You can wrap this up in a table valued function or stored proc and parse in the start and end dates as variables.

    DECLARE @startDate DATETIME
    DECLARE @endDate DATETIME
    
    SET @startDate = '2011-01-01'
    SET @endDate = '2011-01-31';
    
    WITH dates(Date) AS 
    (
        SELECT @startdate as Date
        UNION ALL
        SELECT DATEADD(d,1,[Date])
        FROM dates 
        WHERE DATE < @enddate
    )
    
    SELECT Date
    FROM dates
    OPTION (MAXRECURSION 0)
    GO
    
    0 讨论(0)
  • 2020-11-22 00:53

    I would use something similar to this:

    DECLARE @DATEFROM AS DATETIME
    DECLARE @DATETO AS DATETIME
    DECLARE @HOLDER TABLE(DATE DATETIME)
    
    SET @DATEFROM = '2010-08-10'
    SET @DATETO = '2010-09-11'
    
    INSERT INTO
        @HOLDER
            (DATE)
    VALUES
        (@DATEFROM)
    
    WHILE @DATEFROM < @DATETO
    BEGIN
    
        SELECT @DATEFROM = DATEADD(D, 1, @DATEFROM)
        INSERT 
        INTO
            @HOLDER
                (DATE)
        VALUES
            (@DATEFROM)
    END
    
    SELECT 
        DATE
    FROM
        @HOLDER
    

    Then the @HOLDER Variable table holds all the dates incremented by day between those two dates, ready to join at your hearts content.

    0 讨论(0)
  • 2020-11-22 00:56

    We had a similar problem with BIRT reports in that we wanted to report on those days that had no data. Since there were no entries for those dates, the easiest solution for us was to create a simple table that stored all dates and use that to get ranges or join to get zero values for that date.

    We have a job that runs every month to ensure that the table is populated 5 years out into the future. The table is created thus:

    create table all_dates (
        dt date primary key
    );
    

    No doubt there are magical tricky ways to do this with different DBMS' but we always opt for the simplest solution. The storage requirements for the table are minimal and it makes the queries so much simpler and portable. This sort of solution is almost always better from a performance point-of-view since it doesn't require per-row calculations on the data.

    The other option (and we've used this before) is to ensure there's an entry in the table for every date. We swept the table periodically and added zero entries for dates and/or times that didn't exist. This may not be an option in your case, it depends on the data stored.

    If you really think it's a hassle to keep the all_dates table populated, a stored procedure is the way to go which will return a dataset containing those dates. This will almost certainly be slower since you have to calculate the range every time it's called rather than just pulling pre-calculated data from a table.

    But, to be honest, you could populate the table out for 1000 years without any serious data storage problems - 365,000 16-byte (for example) dates plus an index duplicating the date plus 20% overhead for safety, I'd roughly estimate at about 14M [365,000 * 16 * 2 * 1.2 = 14,016,000 bytes]), a minuscule table in the scheme of things.

    0 讨论(0)
提交回复
热议问题