【问题标题】:How to merge two databases, with same data, but with different PKs, without duplicated fields?如何合并两个数据库,具有相同的数据,但具有不同的 PK,没有重复的字段?
【发布时间】:2014-07-25 15:17:18
【问题描述】:

我有两个 mdb 文件。 如有必要,我也可以将其转换为 MySQL 数据库。

如何将这两个不同的数据库合并为一个?

我们的想法是从两个数据库中获取所有信息并合并为一个,而不复制任何客户端。 问题是两个bd都有相同的客户端,也有不同的客户端,但是客户端的PK并不相同。

每一行都有一个独特的字段,我想它可以以某种方式提供帮助。 知道我该怎么做吗?

【问题讨论】:

  • This forum post 至少是一个好的开始。
  • 结果会是什么样子?引用 id = 2 的数据会发生什么
  • 如果 X 中的字段多于 Y,但 Y 中的一列与 X 的同一列的值不同,该怎么办?
  • 例如说桌上客户端的约翰有一个电话号码 4444?
  • @Strawberry,我已经发布了结果,id 应该来自插入的行。 Brian DeMilia,最完整的,虽然我看到我没有想过如果两者都有相同数量的数据,但数据不同。

标签: mysql database ms-access


【解决方案1】:

选择 UNION 除 PK 之外的所有列将只为您提供不同的行:

insert into new_table (<non-pk columns>)
select <non-pk columns> from tableA
union
select <non-pk columns> from tableB

注意:union 删除重复项。

【讨论】:

  • 非常感谢!你知道如果每个客户都与另一个表相关,比如“购买”,我会怎么做?因为购买也会重复。 “购买”表没有唯一标识符。只有来自客户端的 FK,但它们在两个 bd 上并不相同。
  • 可以,但这是一个不同且更复杂的问题——你应该问一个新问题
  • 感谢您的帮助!
【解决方案2】:

我会运行 UPDATE 来填充其中一个表,其中包含所有可用信息。

假设第一个表具有第二个表的所有名称(表 2 中没有不在表 1 中的名称值),您应该能够运行以下更新以使第一个表完整:

update tclient1 t join (select name,
                               max(tel) as tel_filled,
                               max(address) as add_filled
                          from (select name, tel, address
                                  from tclient1
                                union all
                                select name, tel, address
                                  from tclient2) x
                         group by name) x on t.name = x.name
   set t.tel = x.tel_filled and t.address = x.add_filled;

见小提琴:http://sqlfiddle.com/#!2/3e7dc/1/0

【讨论】:

    【解决方案3】:
    1. 禁用外键(参见here
    2. 更新第二个数据库中的 FK,使它们独一无二,例如:

      更新客户端 设置 id_client = id_client + 100000000;

      更新历史 设置 id_client = id_client + 100000000, id_history = id_history + 10000000;

    3. 启用 FK 检查完整性

    4. 将第二个 DB 导出为 SQL 插入并在第一个 DB 中执行。

    请使用备份。

    【讨论】:

      【解决方案4】:

      这是一种假设name 是两行之间的匹配项的方法。它只是计算填写的数字并选择适当的来源。此版本使用union all 并在where 中使用&gt;=&lt; 进行比较:

      insert into client(id, name, tel, address)
         select id, name, tel, address
         from db1.client c1
         where ((id is not null) + (tel is not null) + (address is not null)) >=
                (select (id is not null) + (tel is not null) + (address is not null)
                 from db2.client c2
                 where c1.name = c2.name
                )
               )
          union all
          select id, name, tel, address
          from db2.client c2
          where ((id is not null) + (tel is not null) + (address is not null)) >
                 (select (id is not null) + (tel is not null) + (address is not null)
                  from db1.client c1
                  where c2.name = c1.name
                 )
                );
      

      注意:以上版本假定name 在两个表中(如您问题中的示例所示)并且没有重复项。如果不是这种情况,可以轻松修改。

      【讨论】:

      • id好像在两个表里都有,但是不一样,例子中是1和2。
      • @dnoeth 。 . .谢谢你指出这一点。我对答案进行了必要的更改。
      猜你喜欢
      • 1970-01-01
      • 2013-11-22
      • 1970-01-01
      • 2013-03-24
      • 1970-01-01
      • 1970-01-01
      • 2015-05-27
      • 2021-12-18
      • 2011-06-07
      相关资源
      最近更新 更多