我正在尝试合并\合并两个数据表。 我查看了各种示例和答案,但它们似乎创建了重复的行或需要索引(在数据表上合并等)
我无法通过SQL执行此操作,因为一个源来自通过MSSQL访问的链接Oracle服务器,另一个源来自不具有链接访问权限的其他MSSQL Server。
目前数据非常简单:
Name, Email, Phone
DataTable1:
"John Clark", "", "01522 55231"
"Alex King", "alex.king@somecompany.com", "01522 55266"
"Marcus Jones", "marcus.jones@somecompany.com", "01522 55461"
DataTable2:
"John Clark", "john.clark@somecompany.com", "01522 55231"
"Alex King", "alex.king@somecompany.com", ""
"Marcus Jones", "marcus.jones@somecompany.com", "01522 55461"
"Warren bean", "warren.bean@somecompany.com", "01522 522311"
使用以下内容提供数据表:
"John Clark", "john.clark@somecompany.com", "01522 55231"
"Alex King", "alex.king@somecompany.com", "01522 55266"
"Marcus Jones", "marcus.jones@somecompany.com", "01522 55461"
"Warren bean", "warren.bean@somecompany.com", "01522 522311"
名称是匹配记录的字段,第一个数据表优先。
答案 0 :(得分:1)
您应该可以使用Union
合并列表,然后列出Distinct
列表。
为了让Distinct工作,您需要实施IEqualityComparer(您还可以将IEqalityComparer
传递给Union
的重载。
例如 - 假设您从每个来源获得了相同Person
类的列表:
Dim allList = dataTable1List.Union(dataTable2List).Distinct(New PersonComparer())
PersonComparer
的示例可能是:
Public Class PersonComparer
Implements IEqualityComparer(Of Person)
Public Overloads Function Equals(ByVal a As Person, ByVal b As Person) As Boolean Implements IEqualityComparer(Of Person).Equals
Return a.Name = b.Name
End Function
Public Overloads Function GetHashCode(ByVal a As Person) As Integer Implements IEqualityComparer(Of Person).GetHashCode
Return a.GetHashCode()
End Function
End Class
答案 1 :(得分:0)
如果一切都失败了,你总是可以使用UNION将2个表合并为1个结果。
select name from datatable1 where ...
UNIION ALL
select name from datatable2 where ...
答案 2 :(得分:0)
答案 3 :(得分:0)
这是一种Linq-To-DataSet
方法,应该是quite efficient,因为它使用Except
和Join
。
Dim t1Names = From t In table1 Select t.Field(Of String)("Name")
Dim t2Names = From t In table2 Select t.Field(Of String)("Name")
Dim newt2Names = t2Names.Except(t1Names)
Dim newT2Rows = From t2 In table2
Join newName In newt2Names
On t2.Field(Of String)("Name") Equals newName
Select t2
Dim updates = From t1 In table1
Join t2 In table2
On t1.Field(Of String)("Name") Equals t2.Field(Of String)("Name")
Where t1.Field(Of String)("Email") <> t2.Field(Of String)("Email") _
OrElse t1.Field(Of String)("Phone") <> t2.Field(Of String)("Phone")
For Each newt2 As DataRow In newT2Rows
Dim newT1 = table1.Rows.Add()
newT1.ItemArray = newt2.ItemArray
Next
For Each u In updates
If String.IsNullOrEmpty(u.t1.Field(Of String)("Email")) Then
u.t1.SetField("Email", u.t2.Field(Of String)("Email"))
End If
If String.IsNullOrEmpty(u.t1.Field(Of String)("Phone")) Then
u.t1.SetField("Phone", u.t2.Field(Of String)("Phone"))
End If
If String.IsNullOrEmpty(u.t2.Field(Of String)("Email")) Then
u.t2.SetField("Email", u.t1.Field(Of String)("Email"))
End If
If String.IsNullOrEmpty(u.t2.Field(Of String)("Phone")) Then
u.t2.SetField("Phone", u.t1.Field(Of String)("Phone"))
End If
Next
请注意,如果您还想从table1到table2添加新行,它可能不完整,但我希望它能为您提供一个想法。
编辑:这是您的样本数据(如果有人想测试):
Dim table1 = New DataTable
Dim table2 = New DataTable
table1.Columns.Add("Name")
table1.Columns.Add("Email")
table1.Columns.Add("Phone")
table2.Columns.Add("Name")
table2.Columns.Add("Email")
table2.Columns.Add("Phone")
table1.Rows.Add("John Clark", "", "01522 55231")
table1.Rows.Add("Alex King", "alex.king@somecompany.com", "01522 55266")
table1.Rows.Add("Marcus Jones", "marcus.jones@somecompany.com", "01522 55461")
table2.Rows.Add("John Clark", "john.clark@somecompany.com", "01522 55231")
table2.Rows.Add("Alex King", "alex.king@somecompany.com", "")
table2.Rows.Add("Marcus Jones", "marcus.jones@somecompany.com", "01522 55461")
table2.Rows.Add("Warren bean", "warren.bean@somecompany.com", "01522 522311")