【问题标题】:How to list all dates between two dates [duplicate]如何列出两个日期之间的所有日期[重复]
【发布时间】:2013-07-05 23:24:54
【问题描述】:

我想在 SQL Server 存储过程中列出两个日期之间的日期。

例如:

Date1: 2015-05-28
Date2: 2015-05-31

结果:

2015-05-29
2015-05-30

如何计算两个给定日期之间的所有日期?

问候,

【问题讨论】:

标签: sql-server stored-procedures


【解决方案1】:

创建一个执行以下操作的存储过程:

declare @startDate date;
declare @endDate date;

select @startDate = '20150528';
select @endDate = '20150531';

with dateRange as
(
  select dt = dateadd(dd, 1, @startDate)
  where dateadd(dd, 1, @startDate) < @endDate
  union all
  select dateadd(dd, 1, dt)
  from dateRange
  where dateadd(dd, 1, dt) < @endDate
)
select *
from dateRange

SQL Fiddle with demo.

或者最好还是创建一个日历表,然后从中选择。

【讨论】:

  • 我认为每个数据库都应该有一个日历表
  • 考虑option (maxrecursion 32767)
【解决方案2】:

您可以使用数字表:

DECLARE @Date1 DATE, @Date2 DATE
SET @Date1 = '20150528'
SET @Date2 = '20150531'

SELECT DATEADD(DAY,number+1,@Date1) [Date]
FROM master..spt_values
WHERE type = 'P'
AND DATEADD(DAY,number+1,@Date1) < @Date2

结果:

╔════════════╗
║    Date    ║
╠════════════╣
║ 2015-05-29 ║
║ 2015-05-30 ║
╚════════════╝

【讨论】:

  • 我不会那样做的。如果我无权访问master怎么办?
  • @LuisLL 这只是一个数字表的简单示例,op 可以使用任何其他表或日历表。它通常比递归 CTE 更快(虽然我喜欢使用它们,但我知道它们会带来性能问题)
  • 如果您需要获得较长的日期范围...例如 15-20 年,则有限制。因为它使用的是表 master..spt_values
  • 不是防弹的,因为 spt_values 的值范围限制为 0-2047。
  • 它是大多数人的最佳解决方案,它很短并且产生的噪音更少,即使它不是最通用的。话虽如此,人们可能想知道为什么使用 SQL 生成数字/日期列表如此困难......
【解决方案3】:

我使用以下方法制作了日历:

http://social.technet.microsoft.com/wiki/contents/articles/22776.t-sql-calendar-table.aspx

然后是传递两个日期的 Store 过程,仅此而已:

USE DB_NAME;
GO

CREATE PROCEDURE [dbo].[USP_LISTAR_RANGO_FECHAS]
@FEC_INICIO date,
@FEC_FIN date
AS
Select Date from CALENDARIO where Date BETWEEN @FEC_INICIO AND @FEC_FIN;

【讨论】:

    【解决方案4】:

    使用这个,

    DECLARE @start_date DATETIME = '2015-02-12 00:00:00.000';
    DECLARE @end_date DATETIME = '2015-02-13 00:00:00.000';
    
    WITH    AllDays
              AS ( SELECT   @start_date AS [Date], 1 AS [level]
                   UNION ALL
                   SELECT   DATEADD(DAY, 1, [Date]), [level] + 1
                   FROM     AllDays
                   WHERE    [Date] < @end_date )
         SELECT [Date], [level]
         FROM   AllDays OPTION (MAXRECURSION 0)
    

    @start_date@end_date 作为 SP 参数传递。

    结果:

    Date                    level
    ----------------------- -----------
    2015-02-12 00:00:00.000 1
    2015-02-13 00:00:00.000 2
    
    (2 row(s) affected)
    

    【讨论】:

      【解决方案5】:

      您可以创建一个传递 2 个日期的存储过程

      CREATE PROCEDURE SELECTALLDATES
      (
      @StartDate as date,
      @EndDate as date
      )
      AS
      Declare @Current as date = DATEADD(DD, 1, @BeginDate);
      
      Create table #tmpDates
      (displayDate date)
      
      WHILE @Current < @EndDate
      BEGIN
      insert into #tmpDates
      VALUES(@Current);
      set @Current = DATEADD(DD, 1, @Current) -- add 1 to current day
      END
      
      Select * 
      from #tmpDates
      
      drop table #tmpDates
      

      【讨论】:

        猜你喜欢
        • 2013-06-14
        • 2019-12-22
        • 1970-01-01
        • 2011-11-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多