2016-07-15 4 views
0

Ich versuche herauszufinden, wie Sie eine Zeile für jeden Monat zwischen einem Zeitraum auswählen. Der Zeitraum beginnt mit dem frühesten Monat innerhalb der Tabelle. Im folgenden Beispiel wird die Startperiode 2016-01-01 sein, aber die Endperiode wird benutzerdefiniert sein, sagen wir 2017-02-01. Meine Tabelle:SELECT Zeile für jeden Monat zwischen Daten

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 

Das Ergebnis ich suche, ist dies:

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 

Im Grunde muss ich die Zeile duplizieren, bis es eine andere Zeile findet oder trifft das Enddatum der Periode, wenn eine andere Reihe ist gefunden, dann diese Zeile duplizieren, bis die Endperiode erreicht ist, während die Monat für jede Zeile inkrementiert wird. Hoffnung, die Sinn macht.

Jede Hilfe würde sehr geschätzt werden.

+1

Sie benötigen einen anderen Kalender-Tabelle, mit allen Terminen gefüllt. Sie können es vor Ihrer Abfrage oder "on the fly" mit einigen CTEs füllen. Zum Beispiel http://stackoverflow.com/questions/5635594/how-to-create-a-calander-table-for-100-year-in-sql – xdd

Antwort

1

Sie benötigen wirklich die Nummern Tabelle für diese Art von Problemen. Ich werde es hier mit Tabelle Variable simulieren, aber bitte suchen Sie nach einem Beispiel, wie man einen richtigen in der Datenbank erstellt.

Hier ist die Lösung:

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

Dank @dean, erstellt eine Nummer Tabelle wie vorgeschlagen, und optimiert die Abfrage leicht nach einem Startdatum, das funktioniert gut. Danke nochmal für deine Hilfe. – DanF

0

Diese Versuchen Sie es Sie fehlende Daten geben, dann versuchen, inert in der Tabelle

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