2017-06-14 43 views
-1

我有一个客户成员记录集,如下所示。通过删除重叠行来缩短连续日期范围

 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 

要求是连续

  • 日期需要被组合成1个时间范围
  • 如果有,该行应该被删除的日期为给定的客户ID的重叠

因此,我的结果集应该看起来像这样

  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 

即对于客户A1,1重叠行被设置为拒绝(IsBad属性设置为true)。 彼此相邻的2行组合成1个日期范围。 但记录号4被保留作为 - 是因为它们是为期一天的间隙(它不是连续的)

的数据被存储在一个List<CustomerMembership>()其中CustomerMembership类有CustomerIdEffectiveDateEndDateIsBad性质。

编辑 - 问题是如何获得所需的输出(第二组数据)给定输入(第一组数据)?

由于提前

+0

[请不要将标记置于问题标题](https://stackoverflow.com/help/tagging) – Liam

+0

这是什么问题? – Liam

+0

请尝试以下方法:var join = from dtdate AsAumerable() 将effdate.Field上的dt.AsEnumerable()中的enddate连接到(“EndDate”).AddDays(1)等于enddate.Field (“EffectiveDate”) 选择新的{effdate = effdate,enddate = enddate}; – jdweng

回答

0

假设,因为记录3被标记为不良记录4不重叠记录3,假设最多两个记录可以被组合成一个记录,这些查询将结合两个记录,然后for循环是查找不良记录的最有效方法。它可以用LINQ来完成,但是它会涉及多次数据传递,以获得小的收益。

// 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();