Get a list of dates between two dates using a function

前端 未结 21 1076
天涯浪人
天涯浪人 2020-11-22 06:25

My question is similar to this MySQL question, but intended for SQL Server:

Is there a function or a query that will return a list of days between two dates? For exa

相关标签:
21条回答
  • 2020-11-22 06:47
    SELECT  dateadd(dd,DAYS,'2013-09-07 00:00:00') DATES
    INTO        #TEMP1
    FROM
    (SELECT TOP 365 colorder - 1 AS DAYS from master..syscolumns 
        WHERE id = -519536829 order by colorder) a
    
    WHERE datediff(dd,dateadd(dd,DAYS,'2013-09-07 00:00:00'),'2013-09-13 00:00:00' ) >= 0 
        AND  dateadd(dd,DAYS,'2013-09-07 00:00:00') <=  '2013-09-13 00:00:00'  
        SELECT * FROM #TEMP1
    
    0 讨论(0)
  • 2020-11-22 06:50

    Definately a numbers table, though tyou may want to use Mark Redman's idea of a CLR proc/assembly if you really need the performance.

    How to create the table of dates (and a super fast way to create a numbers table)

    /*Gets a list of integers into a temp table (Jeff Moden's idea from SqlServerCentral.com)*/
     SELECT TOP 10950 /*30 years of days*/
            IDENTITY(INT,1,1) as N
       INTO #Numbers
       FROM Master.dbo.SysColumns sc1,
            Master.dbo.SysColumns sc2
    
    
    /*Create the dates table*/
    CREATE TABLE [TableOfDates](
        [fld_date] [datetime] NOT NULL,
     CONSTRAINT [PK_TableOfDates] PRIMARY KEY CLUSTERED 
    (
        [fld_date] ASC
    )WITH FILLFACTOR = 99 ON [PRIMARY]
    ) ON [PRIMARY]
    
    /*fill the table with dates*/
    DECLARE @daysFromFirstDateInTheTable int
    DECLARE @firstDateInTheTable DATETIME
    
    SET @firstDateInTheTable = '01/01/1998'
    SET @daysFromFirstDateInTheTable = (SELECT (DATEDIFF(dd, @firstDateInTheTable ,GETDATE()) + 1))
    
    INSERT INTO
          TableOfDates
    SELECT 
          DATEADD(dd,nums.n - @daysFromFirstDateInTheTable, CAST(FLOOR(CAST(GETDATE() as FLOAT)) as DateTime)) as FLD_Date
    FROM #Numbers nums
    

    Now that you have a table of dates, you can use a function (NOT A PROC) like KM's to get the table of them.

    CREATE FUNCTION dbo.ListDates
    (
         @StartDate    DATETIME  
        ,@EndDate      DATETIME
    )
    RETURNS
    @DateList table
    (
        Date datetime
    )
    AS
    BEGIN
    
    /*add some validation logic of your own to make sure that the inputs are sound.Adjust the rest as needed*/
    
      INSERT INTO
        @DateList
      SELECT FLD_Date FROM TableOfDates (NOLOCK) WHERE FLD_Date >= @StartDate AND FLD_Date <= @EndDate
      RETURN
    END
    
    0 讨论(0)
  • 2020-11-22 06:51

    Before you use my function, you need to set up a "helper" table, you only need to do this one time per database:

    CREATE TABLE Numbers
    (Number int  NOT NULL,
        CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    DECLARE @x int
    SET @x=0
    WHILE @x<8000
    BEGIN
        SET @x=@x+1
        INSERT INTO Numbers VALUES (@x)
    END
    

    here is the function:

    CREATE FUNCTION dbo.ListDates
    (
         @StartDate    char(10)  
        ,@EndDate      char(10)
    )
    RETURNS
    @DateList table
    (
        Date datetime
    )
    AS
    BEGIN
    
    
    IF ISDATE(@StartDate)!=1 OR ISDATE(@EndDate)!=1
    BEGIN
        RETURN
    END
    
    INSERT INTO @DateList
            (Date)
        SELECT
            CONVERT(datetime,@StartDate)+n.Number-1
            FROM Numbers  n
            WHERE Number<=DATEDIFF(day,@StartDate,CONVERT(datetime,@EndDate)+1)
    
    
    RETURN
    
    END --Function
    

    use this:

    select * from dbo.ListDates('2010-01-01', '2010-01-13')
    

    output:

    Date
    -----------------------
    2010-01-01 00:00:00.000
    2010-01-02 00:00:00.000
    2010-01-03 00:00:00.000
    2010-01-04 00:00:00.000
    2010-01-05 00:00:00.000
    2010-01-06 00:00:00.000
    2010-01-07 00:00:00.000
    2010-01-08 00:00:00.000
    2010-01-09 00:00:00.000
    2010-01-10 00:00:00.000
    2010-01-11 00:00:00.000
    2010-01-12 00:00:00.000
    2010-01-13 00:00:00.000
    
    (13 row(s) affected)
    
    0 讨论(0)
  • 2020-11-22 06:55

    All you have to do is just change the hard coded value in the code provided below

    DECLARE @firstDate datetime
        DECLARE @secondDate datetime
        DECLARE @totalDays  INT
        SELECT @firstDate = getDate() - 30
        SELECT @secondDate = getDate()
    
        DECLARE @index INT
        SELECT @index = 0
        SELECT @totalDays = datediff(day, @firstDate, @secondDate)
    
        CREATE TABLE #temp
        (
             ID INT NOT NULL IDENTITY(1,1)
            ,CommonDate DATETIME NULL
        )
    
        WHILE @index < @totalDays
            BEGIN
    
                INSERT INTO #temp (CommonDate) VALUES  (DATEADD(Day, @index, @firstDate))   
                SELECT @index = @index + 1
            END
    
        SELECT CONVERT(VARCHAR(10), CommonDate, 102) as [Date Between] FROM #temp
    
        DROP TABLE #temp
    
    0 讨论(0)
  • 2020-11-22 06:56
    DECLARE @MinDate DATETIME = '2012-09-23 00:02:00.000',
        @MaxDate DATETIME = '2012-09-25 00:00:00.000';
    
    SELECT  TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1) Dates = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate)
    FROM sys.all_objects a CROSS JOIN sys.all_objects b;
    
    0 讨论(0)
  • 2020-11-22 06:56
    WITH TEMP (DIA, SIGUIENTE_DIA ) AS
               (SELECT 
                   1, 
                   CAST(@FECHAINI AS DATE)
                FROM 
                   DUAL
               UNION ALL
                SELECT 
                   DIA, 
                   DATEADD(DAY, DIA, SIGUIENTE_DIA)
                FROM 
                   TEMP
                WHERE
                   DIA < DATEDIFF(DAY,  @FECHAINI, @FECHAFIN)   
                   AND DATEADD(DAY, 1, SIGUIENTE_DIA) <=  CAST(@FECHAFIN AS DATE)
               )
               SELECT 
                  SIGUIENTE_DIA AS CALENDARIO 
               FROM
                  TEMP
               ORDER BY   
                  SIGUIENTE_DIA
    

    The detail is on the table DUAL but if your exchange this table for a dummy table this works.

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