2017-06-14 1 views
-1

Ich habe einen Kundenmitgliedschaft Record Sets wie unten gezeigt.Condense konsekutiven Datumsbereich durch Entfernen überlappender Zeilen

 CustomerId | EffectiveDate | EndDate | RecordNo 
     A1 | 01 - 01 - 2016 | 31 - 05 - 2016 | 1 
     A1 | 01 - 06 - 2016 | 31 - 10 - 2016 | 2 
     A1 | 01 - 09 - 2016 | 31 - 12 - 2017 | 3 
     A1 | 02 - 11 - 2016 | 31 - 12 - 2016 | 4 
     A2 | 02 - 11 - 2016 | 31 - 12 - 2016 | 5 

Die Anforderung ist

  • aufeinanderfolgende Daten in 1 Datumsbereich
  • kombiniert werden müssen, wenn es eine Überlappung der Termine für einen bestimmten Kunden-ID ist, sollte die Zeile entfernt werden

Daher sollte mein Ergebnissatz wie folgt aussehen:

  CustomerId | EffectiveDate | EndDate | IsBad 
      A1 | 01 - 01 - 2016 | 31 - 10 - 2016 | false 
      A1 | 01 - 09 - 2016 | 31 - 12 - 2017 | true 
      A1 | 02 - 11 - 2016 | 31 - 12 - 2016 | false 
      A2 | 02 - 11 - 2016 | 31 - 12 - 2016 | false 

Das ist für den Kunden A1, 1 überlappende Zeile wurde auf abgelehnt (IsBad-Eigenschaft wird auf True festgelegt) festgelegt. 2 nebeneinander liegende Zeilen wurden zu einem Datumsbereich zusammengefasst. Aber Rekordzahl 4 wurde beibehalten wie sie ist, da sie eine eintägige Lücke war (war es nicht konsekutiv)

Die Daten in einem List<CustomerMembership>() gespeichert wird, wo die CustomerMembership Klasse CustomerId, EffectiveDate, EndDate und IsBad Eigenschaften hat.

Edit- Die Frage ist, wie bekomme ich die gewünschte Ausgabe (2. Satz von Daten) angesichts der Eingabe (1. Satz von Daten)?

Vielen Dank im Voraus

+0

[Bitte stellen keine Tags in Frage Titel] (https://stackoverflow.com/help/tagging) – Liam

+0

Was ist die Frage? – Liam

+0

Versuchen Sie folgendes: var. = Von effdate in dt.AsEnumerable join() beitreten enddate in dt.AsEnumerable() auf effdate.Field ("EndDate") AddDays (1) gleich enddate.Field ("EffectiveDate") wähle neu {effdate = effdate, enddate = enddate}; – jdweng

Antwort

0

Unter der Annahme, Rekord 4 Datensatz 3 nicht überlappen, weil der Datensatz 3 als schlecht markiert ist, und unter der Annahme, höchstens zwei Datensätze in einen Datensatz kombiniert werden können, werden diese Anfragen die beiden Datensätze kombinieren und dann Die for-Schleife ist der effizienteste Weg, um die fehlerhaften Datensätze zu finden. Es könnte mit LINQ gemacht werden, aber es würde mehrere Durchgänge über Daten für wenig Gewinn beinhalten.

// find records that extend an earlier record 
var step0 = from r1 in src 
      join r2 in src.Skip(1) on new { r1.CustomerId, TestDate = r1.EndDateTime.AddDays(1) } equals new { r2.CustomerId, TestDate = r2.EffectiveDateTime } 
      select new { r1, r2 }; 

// combine extended records and passthru non-extended records 
var step1 = (from r1 in src 
      where !step0.Any(r1r2 => r1 == r1r2.r1) 
      join r1r2 in step0 on r1 equals r1r2.r1 into r1r2j 
      from r1r2 in r1r2j.DefaultIfEmpty() 
      let r2 = r1r2?.r2 
      orderby r1.CustomerId, r1.EffectiveDateTime 
      select new CustomerMembership { CustomerId = r1.CustomerId, EffectiveDateTime = r1.EffectiveDateTime, EndDateTime = (r2 != null) ? r2.EndDateTime : r1.EndDateTime }).ToArray(); 

// find bad records by comparing records to previous record 
for (var j1 = 1; j1 < step1.Length; ++j1) 
    if (!step1[j1-1].IsBad) 
     step1[j1].IsBad = step1[j1].CustomerId == step1[j1-1].CustomerId && 
      (step1[j1].EffectiveDateTime.IsBetween(step1[j1-1].EffectiveDateTime, step1[j1-1].EndDateTime) || 
      step1[j1].EndDateTime.IsBetween(step1[j1-1].EffectiveDateTime, step1[j1-1].EndDateTime)); 

var ans = step1.ToList();