我试图找出如何在一个时期之间为每个月选择一行。该期间将具有表中最早月份的开始日期。因此在下面的示例中,开始时段将是2016-01-01,但结束时段将由用户定义,比如说2017-02-01。我的表:
rowID | Month | someDate | SomeOtherDate | Number
1 | 2016-01-01 | 2018-01-01 | 2018-01-01 | 0
2 | 2016-07-01 | 2019-03-01 | 2019-02-01 | 1
我正在寻找的结果是:
Month | someDate | SomeOtherDate | Number
2016-01-01 | 2018-01-01 | 2018-01-01 | 0
2016-02-01 | 2018-01-01 | 2018-01-01 | 0
2016-03-01 | 2018-01-01 | 2018-01-01 | 0
2016-04-01 | 2018-01-01 | 2018-01-01 | 0
2016-05-01 | 2018-01-01 | 2018-01-01 | 0
2016-05-01 | 2018-01-01 | 2018-01-01 | 0
2016-07-01 | 2019-03-01 | 2019-02-01 | 1
2016-08-01 | 2019-03-01 | 2019-02-01 | 1
2016-09-01 | 2019-03-01 | 2019-02-01 | 1
2016-10-01 | 2019-03-01 | 2019-02-01 | 1
2016-11-01 | 2019-03-01 | 2019-02-01 | 1
2016-12-01 | 2019-03-01 | 2019-02-01 | 1
2017-01-01 | 2019-03-01 | 2019-02-01 | 1
2017-02-01 | 2019-03-01 | 2019-02-01 | 1
基本上我需要复制该行,直到找到另一行或满足句点结束日期,如果找到另一行,则复制该行直到满足结束时段,同时增加月为每一行。希望这是有道理的。
非常感谢任何帮助。
答案 0 :(得分:1)
你真的需要Numbers表来解决这类问题。我将在这里使用表变量来模拟它,但是如果在数据库中创建一个合适的变量,请参阅。
以下是解决方案:
declare @num table(n int)
insert @num values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)
declare @t table (rowID int, Month date, someDate date, SomeOtherDate date, Number int)
insert @t values
(1 , '2016-01-01' , '2018-01-01' , '2018-01-01' , 0 ),
(2 , '2016-07-01' , '2019-03-01' , '2019-02-01' , 1 )
declare @end_date date = '20170201'
set @end_date = dateadd(month, 1, @end_date);
;with x as (
select *, datediff(month, [month], isnull(lead([month]) over(order by rowid), @end_date) ) dd
from @t
)
select dateadd(month, n, [month]) Month, someDate, SomeOtherDate, Number
from x
join @num on dd > n
order by [month]
答案 1 :(得分:0)
尝试这样它会给你丢失的数据,然后尝试在你的表中使用惰性
create table #temp(rowID int,Month datetime,someDate datetime,SomeOtherDate datetime,Number int)
insert into #temp values(1,'2016-01-01','2018-01-01','2018-01-01',0)
insert into #temp values(2,'2016-07-01','2018-03-01','2019-02-01',1)
insert into #temp values(3,'2016-09-01','2018-03-01','2019-02-01',1)
declare @counter int,@Current int
select @counter=count(1) from #temp
set @Current=1
create table #MissingData(rowID int,Month datetime)
while(@counter>@Current)
begin
DECLARE @start datetime,
@end datetime
select @start=Month from #temp where rowID=@Current
select @end=Month from #temp where rowID=@Current+1
if(@end is not null)
begin
;WITH IntervalDates (datetime)
AS
(
SELECT @start
UNION ALL
SELECT DATEADD(MONTH, 1, datetime)
FROM IntervalDates
WHERE DATEADD(MONTH, 1, datetime)<=@end
)
insert into #MissingData
SELECT @Current,convert(datetime,Convert(varchar,YEAR(datetime))+'-'+Convert(varchar,MONTH(datetime))+'-01')
FROM IntervalDates
where convert(datetime,Convert(varchar,YEAR(datetime))+'-'+Convert(varchar,MONTH(datetime))+'-01') not in (@start,@end)
order by YEAR(datetime),MONTH(datetime)
end
select @Current=@Current+1
end
select * from select * from #MissingData