У меня есть список диапазонов дат в таблице, которая может быть открыта и завершена (enddate = null):
Index startdate enddate
1 2018-07-13 NULL
2 2018-11-14 2018-11-16
3 2018-11-15 2018-11-15
Запрос данных теста:
DECLARE @ScheduleTable Table([Index] int not null, StartDate DateTime not null, EndDate DateTime null)
insert into @ScheduleTable ([Index], StartDate, EndDate)
values
(1,'2018-07-13',null)
, (2,'2018-11-14','2018-11-16')
, (3,'2018-11-15','2018-11-15')
select*from @ScheduleTable
Как я могунапишите запрос, который «заполнит дыры» и вернет следующие результаты:
Index startdate enddate
1 2018-07-13 2018-11-13
2 2018-11-14 2018-11-14
3 2018-11-15 2018-11-15
2 2018-11-16 2018-11-16
1 2018-11-17 NULL
Запрос отображения ожидаемых результатов:
select
1 as [Index], '2018-07-13' as StartDate, '2018-11-13' as EndDate
UNION ALL
select
2 as [Index], '2018-11-14', '2018-11-14'
UNION ALL
select
3 as [Index], '2018-11-15', '2018-11-15'
UNION ALL
select
2 as [Index], '2018-11-16', '2018-11-16'
UNION ALL
select
1 as [Index], '2018-11-17', null
Я бы предпочел ответ, который не включает параметры / временную таблицу и т. Д. У меня есть таблица Date Dimension, если это поможет.
В приведенном выше примере запись с Index = 1 является открытой иначинается 7.13.Прервано Index = 2 11.14.Index = 2 затем прерывается Index = 3 11.15.Index = 2, затем начинается снова 11.16.Затем следует индекс = 1, снова запускаемый 11,17Индекс определяет порядок предпочтений, поэтому Индекс = 2 переопределит Индекс = 1 11,14 - 11,16, а Индекс = 3 переопределит Индекс = 2 11,15.Вот мой текущий запрос с использованием lead ():
DECLARE @MinDate DateTime = '2015-01-01'
DECLARE @MaxDate DateTime = '2020-01-01'
select
row_number() over(partition by dealid order by ss.StartDate, ss.id) as [Index]
, ss.startdate
, ss.enddate
, case when ss.enddate is null then
dateadd(d,-1,lead(ss.startdate,1,@MaxDate) over(partition by dealid order by ss.startdate, ss.id))
else ss.enddate end
as EndDate
from
[dbo].[Schedule]ss
where ss.enabled = 1