【问题标题】:select dates between two dates with SQL Server使用 SQL Server 选择两个日期之间的日期
【发布时间】:2019-01-22 09:20:06
【问题描述】:

我有一个 start_date 和 end_date。我想获取这两个日期之间的日期列表。谁能帮我指出查询中的错误。

id      state   start_date      end_date
------------------------------------------------------------------------
2   New     2016-02-24      2016-02-28 
2   Active  2016-02-28      2016-03-01 
2   New     2016-03-01      NULL
3   New     2016-02-23      2016-02-25 
3   Active  2016-02-25      2016-02-27 
3   New     2016-02-27      NULL

id      state   start_date      end_date
------------------------------------------------------------------------
2   New     2016-02-24      2016-02-25 
2   New     2016-02-25      2016-02-26
2   New     2016-02-26      2016-02-27
2   New     2016-02-27      2016-02-28
2   Active  2016-02-28      2016-02-29
2   Active  2016-02-29      2016-03-01
2   New     2016-03-01      NULL
3   New     2016-02-23      2016-02-24 
3   New     2016-02-24      2016-02-25
3   Active  2016-02-25      2016-02-26
3   Active  2016-02-26      2016-02-27 
3   New     2016-02-27      NULL

【问题讨论】:

  • 指出您的查询中的错误,您没有向我们展示?与流行的看法相反,我们不是读心术的人(或者至少,不是所有时候)
  • 一个简单的BETWEENdates 配合得很好。如果您使用字符串而不是日期,它将不起作用。您没有发布任何查询。
  • 添加到上述评论:Bones of SQL - The Calendar Table
  • 还有Temporal Data Techniques in SQL Server。日历表和Numbers 表可以将许多复杂的范围或日期问题转换为简单的联接和范围查询。

标签: sql sql-server


【解决方案1】:

如果您没有可用的日历表,您可以尝试使用master..[spt_values] 来生成缺少的日期。

;WITH cte 
     AS (SELECT ( Row_number() 
                    OVER ( 
                      ORDER BY (SELECT NULL)) ) - 1 RN 
         FROM   master..[spt_values] T1) 
SELECT id, 
       state, Dateadd(day, rn, start_date)     AS start_date, 
       Dateadd(day, rn + 1, start_date) AS end_date 
FROM   <Table_Name> t1 
       INNER JOIN cte T2 
               ON Dateadd(day, rn, start_date) < t1.end_date 

注意:替换为适当的表名。

【讨论】:

    【解决方案2】:

    如果您需要获取两个日期之间的所有日期,最简单的方法是使用递归公用表表达式(并且您可以避免依赖可能在没有通知的情况下更改的未记录系统表):

    declare @start_date date = '2019-1-22';
    declare @end_date date = '2019-1-29';    
    
    with GetDates As  
    (  
      select @start_date as TheDate
      union all  
      select dateadd(day, 1, TheDate) from GetDates where TheDate < @end_date
    )
    select TheDate from GetDates;
    

    现在您可以将数据加入递归 CTE GetDates。

    【讨论】:

      猜你喜欢
      • 2011-07-04
      • 1970-01-01
      • 2015-03-11
      • 2019-11-01
      • 2015-04-01
      • 2017-03-07
      • 2015-07-08
      • 2018-12-26
      • 1970-01-01
      相关资源
      最近更新 更多