2017-11-19 3 views
0

Ich habe eine Tabelle:SQL - Gruppe Reihen von zusammenhängenden Datum

Value Date 
100  01/01/2000 
110  01/05/2002 
100  01/10/2003 
100  01/12/2004 

ich gruppieren möchten die Daten auf diese Weise

Value  StartDate  EndDate 
100   01/01/2000  30/04/2002 
110   01/05/2002  30/09/2003 
100   01/10/2003  NULL --> or value like '01/01/2099' 

Wie kann ich das erreichen? Kann ein CTE nützlich sein und wie?

+2

Geben Sie das verwendete RDBMS an – Mike

+0

Microsoft SQL Server 2012 –

Antwort

0

Für Fensterfunktionen (Beispiel auf MS SQL-Datenbank) RDBMS unterstützt:

with Test(value, dt) as(
    select 100, cast('2000-01-01' as date) union all 
    select 110, cast('2002-05-01' as date) union all 
    select 100, cast('2003-10-01' as date) union all 
    select 100, cast('2004-12-01' as date) 
) 
select max(value) value, min(dt) startDate, max(end_dt) endDate 
    from (
    select a.*, sum(brk) over(order by dt) grp 
     from (
     select t.*, 
       case when value!=lag(value) over(order by dt) then 1 else 0 end brk, 
       DATEADD(DAY,-1,lead(dt,1,cast('2099-01-02' as date)) over(order by dt)) end_dt 
      from Test t 
    ) a 
) b 
group by grp 
order by startDate 
+0

Für MSSQL habe ich das ersetzt: \t _lead (dt, 1, DATE'2099-01-02 ') über (nach dt) -1 end_dt_ ----> ** 'isnull (dateadd (d, -1, führen (dt) über (nach dt)), '29990101') end_dt' ** und scheint gut zu funktionieren –

0

ich glaube, der Unterschied von Zeilennummern in diesem Fall einfacher ist:

select value, min(date) as endDate, 
     dateadd(day, -1, lead(min(date)) over (order by min(date))) as endDate 
from (select t.*, 
      row_number() over (order by date) as seqnum, 
      row_number() over (partition by value order by date) as seqnum_v 
     from t 
    ) t 
group by value, (seqnum - seqnum_v); 

die Differenz der Zeilennummern Definiert die gewünschten Gruppen. Das ist ein bisschen schwer zu sehen. . . Wenn Sie auf die Ergebnisse der Unterabfrage starren, sehen Sie, wie es funktioniert.