【问题标题】:Getting Dates between a range of dates获取一系列日期之间的日期
【发布时间】:2010-09-21 06:12:22
【问题描述】:

我需要使用 SQL Server 2005 获取日期范围内的所有日期

【问题讨论】:

  • 您要生成日期,还是只搜索现有字段?
  • Harish,请将以下回复之一标记为答案。他们花时间帮助你。

标签: sql sql-server tsql datetime date-range


【解决方案1】:

给你:

DECLARE @DateFrom smalldatetime, @DateTo smalldatetime;
SET @DateFrom='20000101';
SET @DateTo='20081231';
-------------------------------
WITH T(date)
AS
( 
SELECT @DateFrom 
UNION ALL
SELECT DateAdd(day,1,T.date) FROM T WHERE T.date < @DateTo
)
SELECT date FROM T OPTION (MAXRECURSION 32767);

【讨论】:

  • 我很喜欢这个解决方案。对时间线使用类似的东西,因此即使在数据库中没有匹配该时间段的记录,图表也会保持一致的间隔。
  • 对。这适用于生成任何序列:只需将 DateAdd(day,1,T.date) 替换为其他一些 this_item=F(previous_item) 公式
  • 带有 CTE 的非常酷的解决方案。我以前从未见过这样做。
  • 这太棒了。我需要一些可以在两个日期之间给我所有星期一的东西。因此,我将它与使用 datepart 和 bam 的附加过滤器一起使用......正是我所需要的。 +1 来自我。
【解决方案2】:

如果您在表格中有日期,并且只想选择两个日期之间的日期,则可以使用

select * from yourTable where yourDate between date1 and date2

如果您想从无到有生成日期,您可以使用循环来完成,或者您可以使用日期填充临时表,然后从中进行选择。

【讨论】:

    【解决方案3】:
    DECLARE @Date1 DATE='2016-12-21', @Date2 DATE='2016-12-25'
    SELECT DATEADD(DAY,number,@Date1) [Date] FROM master..spt_values WHERE type = 'P' AND DATEADD(DAY,number,@Date1) <= @Date2
    

    【讨论】:

    • 这只适用于较小的日期范围。小于 2048 天。
    【解决方案4】:

    这里是日期生成的 Oracle 版本:

    SELECT TO_DATE ('01-OCT-2008') + ROWNUM - 1 g_date
      FROM all_objects
     WHERE ROWNUM <= 15
    

    可以是任何具有足够行数以覆盖所需范围的表,而不是 all_objects。

    【讨论】:

      【解决方案5】:

      稍微复杂一点但可能更灵活的是使用包含一组连续数字的表格。这允许多个具有不同间隔的日期范围。

      /* holds a sequential set of number ie 0 to max */
      /* where max is the total number of rows expected */
      declare @Numbers table ( Number int  )
      
      declare @max int 
      declare @cnt int
      
      set @cnt = 0
      /* this value could be limited if you knew the total rows expected */
      set @max = 999 
      
      /* we are building the NUMBERS table on the fly */
      /* but this could be a proper table in the database */
      /* created at the point of first deployment */
      while (@cnt <= @max)
      begin
            insert into @Numbers select @cnt
            set @cnt = @cnt + 1
      end
      
      /* EXAMPLE of creating dates with different intervals */
      
      declare @DateRanges table ( 
         StartDateTime datetime, EndDateTime datetime, Interval int )
      
      /* example set of date ranges */
      insert into @DateRanges
      select '01 Jan 2009', '10 Jan 2009', 1 /* 1 day interval */
      union select '01 Feb 2009', '10 Feb 2009', 2 /* 2 day interval */
      
      /* heres the important bit generate the dates */
      select
            StartDateTime
      from
      (
            select
                  d.StartDateTime as RangeStart,
                  d.EndDateTime as RangeEnd,
                  dateadd(DAY, d.Interval * n.Number, d.StartDateTime) as StartDateTime
            from 
                  @DateRanges d, @Numbers n
      ) as dates
      where
            StartDateTime between RangeStart and RangeEnd
      order by StartDateTime
      

      我实际上使用了这种方法的变体将日期分成时间段(有不同的时间间隔,但通常为 5 分钟长)。我的@numbers 表最多包含 288 个,因为这是您在 24 小时内可以拥有的 5 分钟插槽总数。

      /* EXAMPLE of creating times with different intervals */
      
      delete from @DateRanges 
      
      /* example set of date ranges */
      insert into @DateRanges
      select '01 Jan 2009 09:00:00', '01 Jan 2009 12:00:00', 30 /* 30 minutes interval */
      union select '02 Feb 2009 09:00:00', '02 Feb 2009 10:00:00', 5 /* 5 minutes interval */
      
      /* heres the import bit generate the times */
      select
            StartDateTime,
            EndDateTime
      from
      (
            select
                  d.StartDateTime as RangeStart,
                  d.EndDateTime as RangeEnd,
                  dateadd(MINUTE, d.Interval * n.Number, d.StartDateTime) as StartDateTime,
                  dateadd(MINUTE, d.Interval * (n.Number + 1) , StartDateTime) as EndDateTime
            from 
                  @DateRanges d, @Numbers n
      ) as dates
      where
            StartDateTime >= RangeStart and EndDateTime <= RangeEnd
      order by StartDateTime
      

      【讨论】:

        【解决方案6】:

        如果您想要获取数据库中两个日期之间的所有日期(即客户在 2008 年第三季度下订单的日期),您可以这样写:

        select distinct(orderPlacedDate) 
        from orders 
        where orderPlacedDate between '2008-07-01' and 2008-09-30' 
        order by orderPlacedDate
        

        【讨论】:

          【解决方案7】:

          要生成日期范围,您可以编写一个表值函数。这是一个为数据仓库创建日期维度的函数 - 您可以通过删除特殊内容来相当容易地调整它。

          编辑:这里没有日期维度层次结构。

          if object_id ('ods.uf_DateHierarchy') is not null
              drop function ods.uf_DateHierarchy
          go
          
          create function ods.uf_DateHierarchy (
                 @DateFrom datetime
                ,@DateTo   datetime
          ) returns @DateHierarchy table (
                  DateKey           datetime
          ) as begin
              declare @today           datetime  
              set @today = @Datefrom
          
              while @today <= @DateTo begin
                  insert @DateHierarchy (DateKey) values (@today)
                  set @today = dateadd (dd, 1, @today)
              end
          
              return
          end
          
          go
          

          【讨论】:

            猜你喜欢
            • 2014-04-19
            • 1970-01-01
            • 2010-10-05
            • 2017-11-16
            • 2018-09-17
            • 2021-11-28
            • 2018-01-11
            • 1970-01-01
            • 2021-12-19
            相关资源
            最近更新 更多