7

FromDate文字列形式のとの 2 つの列を持つデータテーブルがありToDateます。テーブルに重複するレコードがあるかどうかを確認したい.ie

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 を返す必要があります。

4

7 に答える 7

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();
于 2012-07-20T08:04:29.873 に答える
1

ToDateで並べ替えます (または、並べ替えられたFromDateインデックスの配列を DataTable に作成します)。行または配列の位置 #2 から最後までループし、FromDate <= 前の項目の ToDate かどうかを確認します。重複するアイテムをリストに配置します。ジョブ完了。

FromDateで並べ替えて、ToDate同様のロジックを実行することもできます。

于 2012-07-20T08:00:00.550 に答える
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,
            };

おそらく、2 番目の Id を省略したいでしょう (ここで ( 1 / 6) と (6 / 1) が重複するため)。

于 2012-07-20T08:51:55.157 に答える
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

詳細はこちら

于 2012-07-20T07:35:46.877 に答える
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
于 2013-12-20T14:40:01.120 に答える
0

「To Date」列を解析してみてください。それぞれについて、「From Date」列を検索して、後の対応する「To Date」を持つ以前の日付を探します。

于 2012-07-20T07:40:59.820 に答える