2010-12-03 7 views
4

Ich möchte Daten basierend auf Startdatum und Enddatum anzeigen. Ein Code kann verschiedene Daten enthalten. wenn jederzeit intervel wird weiterhin dann muss ich fusionieren, dass Zeilen und Anzeige als einzelne Zeile Hier Beispieldaten istZeilen basierend auf dem Datum in SQL Server zusammenführen

Code Start_Date End_Date  Volume 
470 24-Oct-10 30-Oct-10 28 
470 17-Oct-10 23-Oct-10  2 
470 26-Sep-10  2-Oct-10  2 
471 22-Aug-10 29-Aug-10  2 
471 15-Aug-10 21-Aug-10  2 

Der Ausgang ich will, ist

Code Start_Date End_Date  Volume 
470 17-Oct-10 30-Oct-10 30 
470 26-Sep-10  2-Oct-10  2 
471 15-Aug-10 29-Aug-10  4 

ein Code jedes keine haben kann. der Zeit intervels. Bitte helfen. Danke

+0

In Ihrer Beispielausgabe (jetzt, dass es formated dank KM) Ich bin nicht sicher, warum die die Reihe 470 26-Sep-10 2-Oct-10 2 würde nicht mit dem anderen 470 Code verschmolzen werden? –

+0

wird jedes Paar von Zeilen (für einen bestimmten Code) jemals Datumsbereiche haben, die sich tatsächlich überlappen, oder werden sie immer unterschiedlich sein? –

Antwort

2

Basierend auf Ihren Beispieldaten (die ich in einer Tabelle gesetzt haben als Test bezeichnet wird), und keine Überschneidungen unter der Annahme:

;with Ranges as (
    select Code,Start_Date,End_Date,Volume from Test 
    union all 
    select r.Code,r.Start_Date,t.End_Date,(r.Volume + t.Volume) 
    from 
     Ranges r 
      inner join 
     Test t 
      on 
       r.Code = t.Code and 
       DATEDIFF(day,r.End_Date,t.Start_Date) = 1 
), ExtendedRanges as (
select Code,MIN(Start_Date) as Start_Date,End_Date,MAX(Volume) as Volume 
from Ranges 
group by Code,End_Date 
) 
select Code,Start_Date,MAX(End_Date),MAX(Volume) 
from ExtendedRanges 
group by Code,Start_Date 

Erläuterung:

die Bereiche CTE alle Zeilen aus der ursprünglichen Tabelle enthält (weil einige von ihnen könnten relevant sein) und alle Zeilen wir von joi bilden können Ning Bereiche zusammen (sowohl ursprüngliche Bereiche, und alle Zwischenbereiche, die wir konstruieren - wir machen Rekursion hier).

Dann findet ExtendedRanges (schlecht benannt) für jedes bestimmte End_Date das früheste Start_Date, das es erreichen kann.

Schließlich fragen wir dieses zweite CTE ab, um für jedes bestimmte Startdatum das neueste Enddatum zu finden, das damit verknüpft ist.

Diese beiden Abfragen kombinieren, um den CTE der Bereiche im Grunde nach "dem größtmöglichen Start_Datum/End_Datum-Paar" in jedem Satz überlappender Datumsbereiche zu filtern.

Beispieldatenaufbau:

create table Test (
    Code int not null, 
    Start_Date date not null, 
    End_Date date not null, 
    Volume int not null 
) 
insert into Test(Code, Start_Date, End_Date,  Volume) 
select 470,'24-Oct-10','30-Oct-10',28 union all 
select 470,'17-Oct-10','23-Oct-10',2 union all 
select 470,'26-Sep-10','2-Oct-10',2 union all 
select 471,'22-Aug-10','29-Aug-10',2 union all 
select 471,'15-Aug-10','21-Aug-10',2 
go 
+0

Vielen Dank. Es funktioniert – Bhushan

3

wenn ich Ihre Anfrage zu verstehen, sind Sie auf der Suche nach so etwas wie:

select code, min(Start_date), max(end_date), sum(volume) 
from yourtable 
group by code 
+0

Danke für die Antwort. aber Ihre Abfrage zeigt eine einzelne Zeile pro Code an. in den daten gibt es die lücke zwischen 2-Okt-2010 bis 17-okt-2010. also sollten wir 2 Zeilen für Code 470 bekommen – Bhushan

+0

Ok, aber technisch gibt es eine Lücke von 24 Stunden zwischen der ersten und zweiten Zeile in Ihrer Probe. Wenn es keine Zeitlücke zwischen einer Reihe und der nächsten geben soll, dann sollten Startzeit und Endzeit gleich sein, nein? –

+0

ja genau. Wenn es mehr als 24 Stunden gibt, dann verschmelzen Sie mit anderen Zeilen. – Bhushan

Verwandte Themen