为大于日期列且小于另一个日期列的每一天添加一个新的日期行?
Add a new date row for every day where greater than a date column and less than another date column?
我正在尝试在 SQL 服务器 table 中为两列(开始日期列和结束日期列)之间的每一天添加一个新行。
这是一个示例 table。为订单日期和发货日期之间的每一天添加一个新行,包括开始日期和结束日期。
姓名
出生日期
订购日期
发货日期
约翰·史密斯
2001 年 2 月 24 日
01-12-2021
01-15-2021
M 杰克逊
12-16-1992
03-17-2021
03-20-2021
我的理想输出table是这样的。
姓名
出生日期
订购日期
发货日期
日期范围
约翰·史密斯
2001 年 2 月 24 日
01-12-2021
01-15-2021
01-12-2021
约翰·史密斯
2001 年 2 月 24 日
01-12-2021
01-15-2021
01-13-2021
约翰·史密斯
2001 年 2 月 24 日
01-12-2021
01-15-2021
01-14-2021
约翰·史密斯
2001 年 2 月 24 日
01-12-2021
01-15-2021
01-15-2021
M 杰克逊
12-16-1992
03-17-2021
03-20-2021
03-17-2021
M 杰克逊
12-16-1992
03-17-2021
03-20-2021
03-18-2021
M 杰克逊
12-16-1992
03-17-2021
03-20-2021
03-19-2021
M 杰克逊
12-16-1992
03-17-2021
03-20-2021
03-20-2021
请注意,我有数百行要复制,在某些情况下日期范围可能是几个月,所以不能一一编码,正在寻找可以为我执行此操作的序列查询。
一种方法是递归 CTE:
with cte as (
select Name, Date_of_Birth, Order_Date, Shipping_Date, Order_Date as date_range
from t
union all
select Name, Date_of_Birth, Order_Date, Shipping_Date,
dateadd(day, 1, date_range)
from cte
where date_range < coalesce(shipping_date, convert(date, getdate()))
)
select *
from cte
option (maxrecursion 0);
已更新以捕获 NULL 发货日期
另一种选择是通过临时 tally/numbers table。注意我将天数设置为 5,000。您可以调整到任何合理的数量
例子
Select A.*
,[Date Range] = dateadd(DAY,N,A.[Order Date])
From YourTable A
Join (
Select Top 5000 N=-1+Row_Number() Over (Order By (Select NULL))
From master..spt_values n1 ,master..spt_values n2
) B on N<=datediff(DAY,A.[Order Date],coalesce(A.[Shipping Date],getdate()))
Order By [Date Range] -- optional
结果
我添加了 NULL 发货日期记录
我正在尝试在 SQL 服务器 table 中为两列(开始日期列和结束日期列)之间的每一天添加一个新行。
这是一个示例 table。为订单日期和发货日期之间的每一天添加一个新行,包括开始日期和结束日期。
姓名 | 出生日期 | 订购日期 | 发货日期 |
---|---|---|---|
约翰·史密斯 | 2001 年 2 月 24 日 | 01-12-2021 | 01-15-2021 |
M 杰克逊 | 12-16-1992 | 03-17-2021 | 03-20-2021 |
我的理想输出table是这样的。
姓名 | 出生日期 | 订购日期 | 发货日期 | 日期范围 |
---|---|---|---|---|
约翰·史密斯 | 2001 年 2 月 24 日 | 01-12-2021 | 01-15-2021 | 01-12-2021 |
约翰·史密斯 | 2001 年 2 月 24 日 | 01-12-2021 | 01-15-2021 | 01-13-2021 |
约翰·史密斯 | 2001 年 2 月 24 日 | 01-12-2021 | 01-15-2021 | 01-14-2021 |
约翰·史密斯 | 2001 年 2 月 24 日 | 01-12-2021 | 01-15-2021 | 01-15-2021 |
M 杰克逊 | 12-16-1992 | 03-17-2021 | 03-20-2021 | 03-17-2021 |
M 杰克逊 | 12-16-1992 | 03-17-2021 | 03-20-2021 | 03-18-2021 |
M 杰克逊 | 12-16-1992 | 03-17-2021 | 03-20-2021 | 03-19-2021 |
M 杰克逊 | 12-16-1992 | 03-17-2021 | 03-20-2021 | 03-20-2021 |
请注意,我有数百行要复制,在某些情况下日期范围可能是几个月,所以不能一一编码,正在寻找可以为我执行此操作的序列查询。
一种方法是递归 CTE:
with cte as (
select Name, Date_of_Birth, Order_Date, Shipping_Date, Order_Date as date_range
from t
union all
select Name, Date_of_Birth, Order_Date, Shipping_Date,
dateadd(day, 1, date_range)
from cte
where date_range < coalesce(shipping_date, convert(date, getdate()))
)
select *
from cte
option (maxrecursion 0);
已更新以捕获 NULL 发货日期
另一种选择是通过临时 tally/numbers table。注意我将天数设置为 5,000。您可以调整到任何合理的数量
例子
Select A.*
,[Date Range] = dateadd(DAY,N,A.[Order Date])
From YourTable A
Join (
Select Top 5000 N=-1+Row_Number() Over (Order By (Select NULL))
From master..spt_values n1 ,master..spt_values n2
) B on N<=datediff(DAY,A.[Order Date],coalesce(A.[Shipping Date],getdate()))
Order By [Date Range] -- optional
结果
我添加了 NULL 发货日期记录