我有一个包含两列FromDate
和ToDate
的数据表,它们是字符串格式。
我想检查我的table.i.e中是否有任何重复记录。
From Date To Date
----------------------
9/01/2012 9/16/2012
8/23/2012 8/24/2012
8/25/2012 8/25/2012
8/5/2012 8/6/2012
8/26/2012 8/27/2012
9/15/2012 9/23/2012
该表包含重复记录,因为它们的日期范围是
的映射From Date To Date
----------------------
9/01/2012 9/16/2012
9/15/2012 9/23/2012
它应该返回false。
答案 0 :(得分:1)
按ToDate
,FromDate
排序(或在DataTable中构建排序的索引数组)。从行或数组位置#2循环到结尾,看看FromDate< =到上一个项目的ToDate。将重叠的项目放入列表中。完成工作。
您还可以按FromDate
,ToDate
排序并执行类似的逻辑。
答案 1 :(得分:1)
var query = from row in dt.AsEnumerable()
from row1 in dt.AsEnumerable()
where
(
(
DateTime.Parse(row1.Field<string>("fromDate")) >= DateTime.Parse(row.Field<string>("fromDate")) &&
DateTime.Parse(row1.Field<string>("fromDate")) <= DateTime.Parse(row.Field<string>("toDate"))
)
||
(
DateTime.Parse(row1.Field<string>("toDate")) >= DateTime.Parse(row.Field<string>("fromDate")) &&
DateTime.Parse(row1.Field<string>("toDate")) <= DateTime.Parse(row.Field<string>("toDate"))
)
)
select new
{
fromDate = DateTime.Parse(row1.Field<string>("fromDate")),
toDate = DateTime.Parse(row1.Field<string>("toDate"))
};
//This lst contains the dates which are overlapping
var lst = query.Distinct().ToList();
答案 2 :(得分:1)
那么,一个selfjoin会在这里提供帮助:
我有一个小班的TimePeriod,只是为了满足你的需求
public class TimePeriod
{
public int Id;
public DateTime FromDate { get; set; }
public DateTime ToDate { get; set; }
public static DateTime Parse(string date)
{
var dt = DateTime.Parse(date,
CultureInfo.CreateSpecificCulture("en-US"), DateTimeStyles.RoundtripKind);
return dt;
}
}
然后我有一些TestData
var list = new List();
list.Add(new TimePeriod() { Id = 1, FromDate = TimePeriod.Parse("9/01/2012"), ToDate = TimePeriod.Parse("9/16/2012") });
list.Add(new TimePeriod() { Id = 2, FromDate = TimePeriod.Parse("8/23/2012"), ToDate = TimePeriod.Parse("8/24/2012") });
list.Add(new TimePeriod() { Id = 3, FromDate = TimePeriod.Parse("8/25/2012"), ToDate = TimePeriod.Parse("8/25/2012") });
list.Add(new TimePeriod() { Id = 4, FromDate = TimePeriod.Parse("8/5/2012"), ToDate = TimePeriod.Parse("8/6/2012") });
list.Add(new TimePeriod() { Id = 5, FromDate = TimePeriod.Parse("8/26/2012"), ToDate = TimePeriod.Parse("8/27/2012") });
list.Add(new TimePeriod() { Id = 6, FromDate = TimePeriod.Parse("9/15/2012"), ToDate = TimePeriod.Parse("9/23/2012") });
以下是解决方案:(有一些OraNob的灵感,谢谢你)
var overlaps = from current in list
from compare in list
where
(
(compare.FromDate > current.FromDate &&
compare.FromDate < current.ToDate) ||
(compare.ToDate > current.FromDate &&
compare.ToDate < current.ToDate)
)
select new
{
Id1 = current.Id,
Id2 = compare.Id,
};
也许你想省略第二个ID(因为你会有重复的 这里(1/6)和(6/1)
答案 3 :(得分:0)
使用DataTable.Search()
方法查找DataTable
中是否存在任何记录,这样您就可以在记录中强制执行唯一性。
像这样的东西
string expression;
expression = "FromDate = #9/01/2012# AND ToDate = #9/16/2012#";
DataRow[] foundRows;
// Use the Select method to find all rows matching the filter.
foundRows = table.Select(expression);
if(foundRows.Length > 0)
// Show duplicate message
else
// Insert your new dates
了解更多Go here
答案 4 :(得分:0)
尝试解析&#34; To Date&#34;列和每个,搜索&#34;从日期&#34;任何较早日期的列,具有稍后对应的&#34; To Date&#34;。
答案 5 :(得分:0)
如果处理大型数据表,则应使用@ErikE响应。 这需要更多的代码行,但到目前为止绝对是最有效的。
如果是小表,你更喜欢比较每两行。 你可以使用其他建议。 只是确保阻止行与自身进行比较,并在结果枚举中重复。
var query = from x in list
where list.Exists((y) => x != y &&
x.FromDate <= y.ToDate &&
y.FromDate <= x.ToDate)
select x;
答案 6 :(得分:0)
strong textDeclare @Table Table
(
RowId Int Identity(1, 1) Not Null,
Id NChar(3) Not Null,
StartDate DATETIME Not Null,
EndDate DATETIME Not Null
);
Insert Into @Table (Id, StartDate, EndDate)
Select 'id1', '20131210 10:10', '20131220 10:10' Union All
Select 'id1', '20131211', '20131215' Union All
Select 'id1', '20131201', '20131205' Union All
Select 'id1', '20131206', '20131208' Union All
Select 'id1', '20131225 10:10', '20131225 10:11'
Select *
From @Table;
With Overlaps (OverlapRowId, BaseRowId, OStart, OEnd, BStart, BEnd)
As
(
Select Overlap.RowId, Base.RowId, Overlap.StartDate, Overlap.EndDate, Base.StartDate, Base.EndDate
From @Table As Base
Inner Join @Table As Overlap On Overlap.Id = Base.Id
Where (((Overlap.StartDate > Base.StartDate) And (Overlap.StartDate < Base.EndDate))
Or ((Overlap.StartDate = Base.StartDate) And (Overlap.EndDate > Base.EndDate)))
And (Base.RowId != Overlap.RowId)
)
-- Remove records that were found to cause overlap issues.
Delete T
From @Table As T
Inner Join
(
Select O.OverlapRowId
From Overlaps As O
Left Join Overlaps As Fp On Fp.OverlapRowId = O.BaseRowId
Where (Fp.OverlapRowId Is Null)
) As SubQuery On SubQuery.OverlapRowId = T.RowId;
-- Select the valid options.
Select RowId, Id, StartDate, EndDate
From @Table where StartDate<EndDate;
Go