合并\合并两个数据表

时间:2012-09-03 21:22:43

标签: sql vb.net linq

我正在尝试合并\合并两个数据表。 我查看了各种示例和答案,但它们似乎创建了重复的行或需要索引(在数据表上合并等)

我无法通过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"

名称是匹配记录的字段,第一个数据表优先。

4 个答案:

答案 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)

  1. 您可以执行一个小应用程序(使用任何编程语言),它将连接到两个dbs并执行所有比较和合并。
  2. 您可以在第一个mssql服务器中从oracle复制您的表,之后您可以从第一个mssql服务器导出/备份您的数据并导入/恢复到临时表中的第二个mssql服务器,之后您可以执行所有操作通过仅使用sql来合并数据
  3. 的魔力
  4. 您可以直接从oracle中导出csv文件中的数据,之后您将导入临时表中的第二个msssql服务器,并且您将能够通过仅使用t-sql进行所有合并

答案 3 :(得分:0)

这是一种Linq-To-DataSet方法,应该是quite efficient,因为它使用ExceptJoin

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")