将多月记录拆分为单独的月份
Split multi-month records into individual months
我在 table 中有这种格式的数据 - 其中日期范围是多月:
SourceSink Class ShadowPrice Round Period StartDate EndDate
AEC Peak 447.038 3 WIN2020 2020-12-01 2021-02-28
我想创建一个视图/插入一个新的 table - 以上记录按月打破,如下所示:
SourceSink Class ShadowPrice Round Period StartDate EndDate
AEC Peak 447.038 3 WIN2020 2020-12-01 2021-12-31
AEC Peak 447.038 3 WIN2020 2021-01-01 2021-01-31
AEC Peak 447.038 3 WIN2020 2021-02-01 2021-02-28
请指教
一个选项是递归查询。假设经期总是从一个月的第一天开始到一个月的最后一天结束,如示例数据所示,则为:
with cte as (
select t.*, startDate newStartDate, eomonth(startDate) newEndDate
from mytable t
union all
select
sourceSink,
class,
shadowPrice,
period,
startDate,
endDate,
dateadd(month, 1, newStartDate),
eomonth(dateadd(month, 1, newStartDate))
from cte
where newStartDate < endDate
)
select * from cte
如果月经开始和结束的日期不同,那么我们需要多一点逻辑:
with cte as (
select
t.*,
startDate newStartDate,
case when eomonth(startDate) <= endDate then eomonth(startDate) else endDate end newEndDate
from mytable t
union all
select
sourceSink,
class,
shadowPrice,
period,
startDate,
endDate,
dateadd(month, 1, datefromparts(year(newStartDate), month(newStartDate), 1)),
case when eomonth(dateadd(month, 1, datefromparts(year(newStartDate), month(newStartDate), 1))) <= endDate
then eomonth(dateadd(month, 1, datefromparts(year(newStartDate), month(newStartDate), 1)))
else endDate
end
from cte
where datefromparts(year(newStartDate), month(newStartDate), 1) < endDate
)
select * from cte
只是使用 CROSS APPLY
和临时计数 table
的另一种选择
例子
Select A.[SourceSink]
,A.[Class]
,A.[ShadowPrice]
,A.[Round]
,A.[Period]
,B.[StartDate]
,B.[EndDate]
From YourTable A
Cross Apply (
Select StartDate=min(D)
,EndDate =max(D)
From (
Select Top (DateDiff(DAY,[StartDate],[EndDate])+1)
D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),[StartDate])
From master..spt_values n1,master..spt_values n2
) B1
Group By Year(D),Month(D)
) B
Returns
我在 table 中有这种格式的数据 - 其中日期范围是多月:
SourceSink Class ShadowPrice Round Period StartDate EndDate
AEC Peak 447.038 3 WIN2020 2020-12-01 2021-02-28
我想创建一个视图/插入一个新的 table - 以上记录按月打破,如下所示:
SourceSink Class ShadowPrice Round Period StartDate EndDate
AEC Peak 447.038 3 WIN2020 2020-12-01 2021-12-31
AEC Peak 447.038 3 WIN2020 2021-01-01 2021-01-31
AEC Peak 447.038 3 WIN2020 2021-02-01 2021-02-28
请指教
一个选项是递归查询。假设经期总是从一个月的第一天开始到一个月的最后一天结束,如示例数据所示,则为:
with cte as (
select t.*, startDate newStartDate, eomonth(startDate) newEndDate
from mytable t
union all
select
sourceSink,
class,
shadowPrice,
period,
startDate,
endDate,
dateadd(month, 1, newStartDate),
eomonth(dateadd(month, 1, newStartDate))
from cte
where newStartDate < endDate
)
select * from cte
如果月经开始和结束的日期不同,那么我们需要多一点逻辑:
with cte as (
select
t.*,
startDate newStartDate,
case when eomonth(startDate) <= endDate then eomonth(startDate) else endDate end newEndDate
from mytable t
union all
select
sourceSink,
class,
shadowPrice,
period,
startDate,
endDate,
dateadd(month, 1, datefromparts(year(newStartDate), month(newStartDate), 1)),
case when eomonth(dateadd(month, 1, datefromparts(year(newStartDate), month(newStartDate), 1))) <= endDate
then eomonth(dateadd(month, 1, datefromparts(year(newStartDate), month(newStartDate), 1)))
else endDate
end
from cte
where datefromparts(year(newStartDate), month(newStartDate), 1) < endDate
)
select * from cte
只是使用 CROSS APPLY
和临时计数 table
例子
Select A.[SourceSink]
,A.[Class]
,A.[ShadowPrice]
,A.[Round]
,A.[Period]
,B.[StartDate]
,B.[EndDate]
From YourTable A
Cross Apply (
Select StartDate=min(D)
,EndDate =max(D)
From (
Select Top (DateDiff(DAY,[StartDate],[EndDate])+1)
D=DateAdd(DAY,-1+Row_Number() Over (Order By (Select Null)),[StartDate])
From master..spt_values n1,master..spt_values n2
) B1
Group By Year(D),Month(D)
) B
Returns