2016-07-15 5 views
0

Я пытаюсь определить, как выбрать строку для каждого месяца между периодом. Период будет иметь дату начала самого раннего месяца в таблице. Таким образом, в приведенном ниже примере начальный период будет 2016-01-01, но конечный период будет определяться пользователем, скажем, 2017-02-01. Мой стол:SELECT строка для каждого месяца между датами

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 

По сути мне нужно дублировать строку до тех пор, пока не найдет другую строку или соответствует дата окончания периода, если другая строка затем дублирует эту строку до тех пор, пока не будет выполнен конечный период, при этом увеличивая значение месяца для каждой строки. Надеюсь, это имеет смысл.

Любая помощь была бы принята с благодарностью.

+1

Вам нужна другая таблица календаря, наполненную всех даты. Вы можете заполнить его перед запросом или «на лету» с некоторыми CTE. Например http://stackoverflow.com/questions/5635594/how-to-create-a-calender-table-for-100-years-in-sql – xdd

ответ

1

Вам действительно нужна таблица чисел для таких проблем. Я буду симулировать его здесь с переменной таблицы, но plsREKOK вокруг для того, чтобы напомнить, как создать правильный в базе данных.

Вот решение:

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] 
+0

Спасибо @dean, создал таблицу чисел, как было предложено, и изменил запросите немного, чтобы включить дату начала, которая отлично работает. В очередной раз благодарим за помощь. – DanF

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 [email protected] 
    select @end=Month from #temp where [email protected]+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)<[email protected] 
     ) 
     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 @[email protected]+1 
end 

select * from select * from #MissingData 
Смежные вопросы