2015-08-19 17 views
5

Was ich versuche zu tun ist, Zeiträume auszuwählen, in denen der Rest der Daten in der Tabelle basierend auf einer Spalte stabil war und es eine Änderung in der zweiten Spalte gab Zeitraum.SQL Server - Auswählen von Zeiträumen ohne Datenänderungen

Tabelle:

create table #stable_periods 
(
[Date]    date, 
[Car_Reg]   nvarchar(10), 
[Internal_Damages] int, 
[External_Damages] int 
) 

insert into #stable_periods 
values ('2015-08-19', 'ABC123', 10, 10), 
     ('2015-08-18', 'ABC123', 9, 10), 
     ('2015-08-17', 'ABC123', 8, 9), 
     ('2015-08-16', 'ABC123', 9, 9), 
     ('2015-08-15', 'ABC123', 10, 10), 
     ('2015-08-14', 'ABC123', 10, 10), 
     ('2015-08-19', 'ABC456', 5, 3), 
     ('2015-08-18', 'ABC456', 5, 4), 
     ('2015-08-17', 'ABC456', 8, 4), 
     ('2015-08-16', 'ABC456', 9, 4), 
     ('2015-08-15', 'ABC456', 10, 10), 
     ('2015-01-01', 'ABC123', 1, 1), 
     ('2015-01-01', 'ABC456', NULL, NULL); 

--select * from #stable_periods 
-- Unfortunately I can’t post pictures yet but you get the point of how the table looks like 

Was Ich mag würde, ist

Car_Reg \t FromDate \t ToDate \t   External_Damages Have internal damages changed in this period? 
 
ABC123 \t 2015-08-18 \t 2015-08-19 \t 10 \t    Yes 
 
ABC123 \t 2015-08-16 \t 2015-08-17 \t 9 \t    Yes 
 
ABC123 \t 2015-08-14 \t 2015-08-15 \t 10 \t    No 
 
ABC123 \t 2015-01-01 \t 2015-01-01 \t 1 \t    No 
 
ABC456 \t 2015-08-19 \t 2015-08-19 \t 3 \t    No 
 
ABC456 \t 2015-08-16 \t 2015-08-18 \t 4 \t    Yes 
 
ABC456 \t 2015-08-15 \t 2015-08-15 \t 10 \t    No 
 
ABC456 \t 2015-01-01 \t 2015-01-01 \t NULL \t    NULL

Grundsätzlich erhalten Zeitraum Rahmen zu bauen, wo [External_Damages] waren konstant und Kontrolle haben die [Internal_Damages ] Änderung in der gleichen Zeit (egal wie oft). Ich verbringe viel Zeit mit dem Versuch, aber ich habe Angst, dass mein Abstraktionsniveau in viel zu niedrig denken ... Wird toll sein, irgendwelche Vorschläge zu sehen.

Danke,

Bartosz

Antwort

5

Ich glaube, das ist eine Form der Islands Problem ist.

Hier wird eine Lösung mit ROW_NUMBER und GROUP BY:

SQL Fiddle

WITH CTE AS(
    SELECT *, 
     RN = DATEADD(DAY, - ROW_NUMBER() OVER(PARTITION BY Car_reg, External_Damages ORDER BY [Date]), [Date]) 
    FROM #stable_periods 
) 
SELECT 
    Car_Reg, 
    FromDate = MIN([Date]), 
    ToDate = MAX([Date]) , 
    External_Damages, 
    Change = 
      CASE 
       WHEN MAX(External_Damages) IS NULL THEN NULL 
       WHEN COUNT(DISTINCT Internal_Damages) > 1 THEN 'Yes' 
       ELSE 'No' 
      END  
FROM CTE c 
GROUP BY Car_Reg, External_Damages, RN 
ORDER BY Car_Reg, ToDate DESC 
+0

Gibt es eine Möglichkeit, die fehlenden Tage in Dataset umgehen konnte? Angenommen, in den umgebenden Zeiträumen [External_Damages] sind sie gleich, dann sind sie in den fehlenden Tagen dieselben und wir können eine längere Periode erstellen, anstatt nur wenige, die durch fehlende Tage in Daten unterbrochen werden. –

+0

@BartoszX, ich schlage vor, Sie erstellen eine neue Frage dafür. –

Verwandte Themen