有一些非常相似的问题,但不一样。 我必须解决下一个问题: 从具有这种结构的表
| DATE_FROM | DATE_TO |
|------------|------------|
| 2010-05-17 | 2010-05-19 |
| 2017-01-02 | 2017-01-04 |
| 2017-05-01 | NULL |
| 2017-06-12 | NULL |
我需要获得一个如下所示的列表
| DATE_LIST |
|------------|
| 2010-05-17 |
| 2010-05-18 |
| 2010-05-19 |
| 2017-01-02 |
| 2010-01-03 |
| 2010-01-04 |
| 2017-05-01 |
| 2017-06-12 |
如何使用SQL获取它? SQL Server 2016。
答案 0 :(得分:3)
一种方法使用递归CTE:
with cte as (
select date_from as date_list, date_to
from t
union all
select dateadd(day, 1, date_from), date_to
from cte
where date_from < date_to
)
select date_list
from cte;
默认情况下,递归CTE的递归深度限制为100(然后返回错误)。这适用于长达100天的跨度。您可以使用OPTION (MAXRECURSION 0)
删除限制。
答案 1 :(得分:3)
另一种选择是使用CROSS APPLY和ad-hoc计数表
Select Date_List=B.D
from YourTable A
Cross Apply (
Select Top (DateDiff(DAY,[DATE_FROM],IsNull([DATE_TO],[DATE_FROM]))+1) D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),[DATE_FROM])
From master..spt_values n1,master..spt_values n2
) B
返回
Date_List
2010-05-17
2010-05-18
2010-05-19
2017-01-02
2017-01-03
2017-01-04
2017-05-01
2017-06-12
答案 2 :(得分:2)
虽然您可以在查询中动态创建日期范围,但请考虑创建永久日历表。这将提供更好的性能,并可以扩展其他属性,如星期几,财政季度等。您可以找到许多通过互联网搜索加载此类表的示例。
以下是40年日期的例子。
{{1}}