我的客户会员记录集如下所示。
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
要求是
因此我的结果集应如下所示
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
对于Customer A1,1个重叠行被设置为拒绝(IsBad属性设置为true)。 彼此相邻的2行组合成1个日期范围。 但是记录号4保持原样,因为它们是一天的间隙(它不是连续的)
数据存储在List<CustomerMembership>()
CustomerMembership
类中CustomerId
,EffectiveDate
,EndDate
和IsBad
属性。
编辑 - 问题是如何在给定输入(第一组数据)的情况下获得所需的输出(第二组数据)?
先谢谢
答案 0 :(得分:0)
假设记录4没有重叠记录3,因为记录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();