从数据集中删除重复项但记录已删除的行

时间:2016-12-21 18:22:46

标签: sql vb.net linq

我从一个SQL表中检索数据,其中我需要将表中的PK输入的值可以来自两个字段之一。

这意味着我可以获得重复项,因此我需要在摄取到目标表之前明显删除它们。

我还需要将我没有摄取的重复记录标记为已处理,这样他们就不会再次被提取,所以我会收集" ID"源表中的值(将是唯一的)用于数组中的重复行。目前我的代码工作正常,只是担心大型数据集可能会很慢(我预计最多可能会有大约50-60K行)。

If ds.Tables(0).Rows.Count > 0 Then
        Dim DupeID_List = Nothing
        Dim DupeID_Count As Integer = 0
        Dim hTable As New Hashtable()
        Dim duplicateList As New ArrayList()
        For Each drow__1 As DataRow In ds.Tables(0).Rows
            If hTable.Contains(drow__1("EIBItemID")) Then
                ReDim Preserve DupeID_List(DupeID_Count)
                duplicateList.Add(drow__1)
                DupeID_List(DupeID_Count) = CStr(drow__1("ID"))
                DupeID_Count = DupeID_Count + 1
            Else
                hTable.Add(drow__1("EIBItemID"), String.Empty)
            End If
        Next
        For Each dRow__2 As DataRow In duplicateList
            ds.Tables(0).Rows.Remove(dRow__2)
        Next
        If Not DupeID_List Is Nothing Then
            Call MarkDupeRecordsExported(DupeID_List)
        End If
        Return ds
    Else
        Return Nothing
    End If

是否有更好的方法来实现相同的目标,检查重复的" EIBItemID"值并将它们从将被批量复制到目标表的数据集中删除,但是为每个被删除的记录(ID)更新源表?

3 个答案:

答案 0 :(得分:0)

使用linq with distinct;

示例:

Dim nonDublicatesTable = From row In ds.Tables(0).AsEnumerable()
            Select row.Field(Of String)("uniquefield") Distinct

然后截断ds.Tables(0)并将nonDublicatesTable数据放到ds.Tables(0)

或者您可以查看这些主题的答案:Delete all Duplicate Rows except for One in MySQL?

答案 1 :(得分:0)

您可以在循环数据表的行时尝试使用Hashset。 对于每一行,您可以将Id添加到Hashset,并通过计算存储在其中的元素来检查它是否已添加。 如果在尝试添加Id后Hashset计数保持不变,则表示您尝试添加的ID已在Hashset中。 知道了这一点,就可以将行添加到具有相同字段(克隆)的新数据表中。 在循环结束时,您将所有具有重复ID的行放入新数据表中。

''Use an HashSet to store Ids
Dim IdsWithoutDup as Hashset(Of YourIdType)'Pseudocode, Use the correct Type
'Use a DataTable to store dulicated Rows
Dim DupRows As DataTable = ds.Tables(0).Clone()

For Each drow__1 As DataRow In ds.Tables(0).Rows
    Dim PreCount = IdsWithoutDup.Count
    IdsWithoutDup.Add(drow__1("EIBItemID"))
    'If Id wasn't added to HashSet (because it's already in)
    'Then add the row to the cloned table
    If IdsWithoutDup.Count = PreCount Then
        DupRows.Add(drow__1)
    End If
    '... do other stuff you need
Next

答案 2 :(得分:0)

从提供的答案中取出一些元素,将其至少减少到一个循环

    If ds.Tables(0).Rows.Count > 0 Then
        Dim NonDupesDT As DataTable = ds.Tables(0).Clone
        Dim DupeID_List = Nothing
        Dim DupeID_Count As Integer = 0
        Dim hTable As New Hashtable()
        For Each drow__1 As DataRow In ds.Tables(0).Rows
            If hTable.Contains(drow__1("EIBItemID")) Then
                ReDim Preserve DupeID_List(DupeID_Count)
                DupeID_List(DupeID_Count) = CStr(drow__1("ID"))
                DupeID_Count = DupeID_Count + 1
            Else
                hTable.Add(drow__1("EIBItemID"), String.Empty)
                NonDupesDT.Rows.Add(drow__1.ItemArray)
            End If
        Next
        If Not DupeID_List Is Nothing Then
            Call MarkDupeRecordsExported(DupeID_List)
        End If
        Return NonDupesDT
    Else
        Return Nothing
    End If

这样我可以创建重复项的“ID”值列表,然后在ELSE中将行添加到新表中,每个副本只有一个版本“EIBItemID”

然后,我可以将新表格传回,有效删除重复项,并使用数组将重复项ID标记为已处理,以便下次运行时不会将其拉出。