使用新的开始日期和结束日期为每个值创建剧集
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用新的开始日期和结束日期为每个值创建剧集相关的知识,希望对你有一定的参考价值。
这是参考下面的问题
Loop through each value to the seq num
但现在客户希望以不同的方式查看数据并为此问题启动新线程。以下是要求。
This is the data .
ID seqNum DOS Service End Date
1 1 1/1/2017 1/15/2017
1 2 1/16/2017 1/16/2017
1 3 1/17/2017 1/21/2017
1 4 1/22/2017 2/13/2017
1 5 2/14/2017 3/21/2017
1 6 2/16/2017 3/21/2017
Expected outPut:
ID SeqNum DOSBeg DOSEnd
1 1 1/1/2017 1/30/2017
1 2 1/31/2017 3/1/2017
1 3 3/2/2017 3/31/2017
For each DOSBeg, add 29 and that is DOSEnd. then Add 1 to DOSEnd (1/31/2017) is new DOSBeg.
Now add 29 to (1/31/2017) and that is 3/1/2017 which is DOSEnd . Repeat this untill DOSend >=Max End Date i.e 3/21/2017.
基本上,每个ID我们需要29天的剧集。
我试过这个代码,它给了我重复。
with cte as (
select ID, minDate as DOSBeg,dateadd(day,29,mindate) as DOSEnd
from #temp
union all
select ID,dateadd(day,1,DOSEnd) as DOSBeg,dateadd(day,29,dateadd(day,1,DOSEnd)) as DOSEnd
from cte
)
select ID,DOSBeg,DOSEnd
from cte
OPTION (MAXRECURSION 0)
Here mindate is Minimum DOS for this ID i.e. 1/1/2017
我提出了以下逻辑,这对我来说很好。还有比这更好的方法吗?
declare @table table (id int, seqNum int identity(1,1), DOS date, ServiceEndDate date)
insert into @table
values
(1,'20170101','20170115'),
(1,'20170116','20170116'),
(1,'20170117','20170121'),
(1,'20170122','20170213'),
(1,'20170214','20170321'),
(1,'20170216','20170321'),
(2,'20170101','20170103'),
(2,'20170104','20170118')
select * into #temp from @table
--drop table #data
select distinct ID, cast(min(DOS) over (partition by ID) as date) as minDate
,row_Number() over (partition by ID order by ID, DOS) as SeqNum,
DOS,
max(ServiceEndDate) over (partition by ID)as maxDate
into #data
from #temp
--drop table #StartDateLogic
with cte as
(select ID,mindate as startdate,maxdate
from #data
union all
select ID,dateadd(day,30,startdate) as startdate,maxdate
from cte
where maxdate >= dateadd(day,30,startdate))
select distinct ID,startdate
into #StartDateLogic
from cte
OPTION (MAXRECURSION 0)
--final Result set
select ID
,ROW_NUMBER() over (Partition by ID order by ID,StartDate) as SeqNum
,StartDate
,dateadd(day,29,startdate) as EndDate
from #StartDateLogic
答案
@scsimon。
如果以下是我的数据集,那么我没有得到ID = 2。我只得到第一个ID = 1。
declare @table table (id int, seqNum int identity(1,1), DOS date, ServiceEndDate date)
insert into @table
values
(1,'20170101','20170115'),
(1,'20170116','20170116'),
(1,'20170117','20170121'),
(1,'20170122','20170213'),
(1,'20170214','20170321'),
(1,'20170216','20170321'),
(2,'20170101','20170103'),
(2,'20170104','20170118')
declare @startDate date = (select min(DOS) from @table)
declare @endDate date = (select max(ServiceEndDate) from @table)
;with dates as(
select top 1 id, seqnum, DOSBeg = DOS, DOSEnd = dateadd(day,29,DOS)
from @table
order by seqNum
union all
select id, seqNum + 1, DOSBeg = dateadd(day,1,DOSEnd), DOSEnd = dateadd(day,29,dateadd(day,1,DOSEnd))
from dates
where DOSEnd <= @endDate)
select *
from dates
with my given data,
i would like to have ID=1 along with ID=2
ID SeqNum DOSBeg DOSend
2 1 20170101 20170130
有什么想法吗?
另一答案
您使用递归cte在正确的轨道上,但是您忘记了锚点。
declare @table table (id int, seqNum int identity(1,1), DOS date, ServiceEndDate date)
insert into @table
values
(1,'20170101','20170115'),
(1,'20170116','20170116'),
(1,'20170117','20170121'),
(1,'20170122','20170213'),
(1,'20170214','20170321'),
(1,'20170216','20170321'),
(2,'20170101','20170103'),
(2,'20170104','20170118')
;with dates as(
select top 1 with ties id, seqnum, DOSBeg = DOS, DOSEnd = dateadd(day,29,DOS)
from @table
order by row_number() over (partition by id order by seqnum)
union all
select t.id, t.seqNum, DOSBeg = dateadd(day,1,d.DOSEnd), DOSEnd = dateadd(day,29,dateadd(day,1,d.DOSEnd))
from dates d
inner join @table t on
d.id = t.id and t.seqNum = d.seqNum + 1
)
select *
from dates d
where d.DOSEnd <= (select max(dateadd(month,1,ServiceEndDate)) from @table where id = d.id)
order by id, seqNum
以上是关于使用新的开始日期和结束日期为每个值创建剧集的主要内容,如果未能解决你的问题,请参考以下文章