【问题标题】:Select Dates Between Two Column Values选择两列值之间的日期
【发布时间】:2010-01-14 20:28:08
【问题描述】:

如果我有一个包含 StartDate 列和 EndDate 列的表,我可以生成一个查询,该查询返回一个集合,包括该范围内的每一天。我可以使用表变量并执行一些程序代码,但我想知道是否有办法在查询中执行此操作。

例如StartDate = 1/1/2010,EndDate = 1/5/2010,结果为:

  • 1/1/2010
  • 1/2/2010
  • 1/3/2010
  • 2010 年 1 月 4 日
  • 2010 年 1 月 5 日

...对于表中具有 StartDate 和 EndDate 列的每一行。

*我使用的是 SQL 2005

【问题讨论】:

    标签: sql sql-server sql-server-2005 tsql


    【解决方案1】:

    SQL Server 2005+:

    WITH dates AS (
       SELECT t.startdate 'date'
         FROM TABLE t
        WHERE t.startdate = '1/1/2010'
       UNION ALL
       SELECT DATEADD(dd, 1, t.date) 
         FROM dates t
        WHERE DATEADD(dd, 1, t.date) <= (SELECT t.enddate FROM TABLE t WHERE t.enddate = '1/5/2010'))
    SELECT ...
      FROM TABLE t
      JOIN dates d ON d.date = t.date
    

    如果您的日期相隔不超过 2047 天:

    SELECT DATEADD(day, 
                   n.number, 
                   (SELECT t.startdate FROM TABLE t WHERE t.startdate = '1/1/2010')
                   )
      FROM (SELECT DISTINCT number 
              FROM MASTER.dbo.SPT_VALUES
             WHERE name IS NULL) n
     WHERE DATEADD(day, n.number, (SELECT t.startdate FROM TABLE t WHERE t.startdate = '1/1/2010')) <= (SELECT t.endate FROM TABLE t WHERE t.endate = '1/5/2010')
    

    【讨论】:

    • 使用递归 CTE 生成序列:EVIL。但你确实列出了spt_values 方法,所以我会告诉你重点。
    • @Aaronaught:递归 CTE 比使用 NUMBERS 表技巧更有效。不知道 SPT_VALUES
    • @Aaronaught:为什么它是邪恶的——尾端递归只是一个循环。
    • @Hogan:尾递归可以转换为循环,但这并不意味着它总是如此。设置OPTION (MAXRECURSION 10)(或类似的)会导致失败,这至少告诉我它实际上是递归执行的。
    【解决方案2】:
    with DateList as 
    ( 
          select cast('1/1/2010' as datetime) DateValue 
          union all 
          select DateValue + 1 
          from    DateList     
          where   DateValue + 1 >= '1/1/2010' AND DateValue +1 <= '1/5/2010' 
    ) 
    select CONVERT(varchar, DateValue, 101) 
    from    DateList 
    
    OPTION (MAXRECURSION 0) 
    

    【讨论】:

    • 这不是他要问的。他想要一份开始日期和结束日期之间所有日历日期的列表,而不是他表中的日期。
    猜你喜欢
    • 2011-11-03
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-26
    • 2017-03-07
    相关资源
    最近更新 更多