Como posso mesclar duas tabelas MySQL?

92

Como posso mesclar duas tabelas MySQL que possuem a mesma estrutura?

As chaves primárias das duas tabelas entrarão em conflito, então levei isso em consideração.

Steve McLeod
fonte
6
Quando você diz que os PKs podem entrar em conflito, você quer dizer que pode haver linhas duplicadas e você não quer que eles sejam copiados, ou que você precisa atribuir um novo PK para um deles porque eles são linhas realmente diferentes, apesar de ter o mesmo PK? (mais uma razão para usar chaves primárias naturais)
Tom H,

Respostas:

123

Você também pode tentar:

INSERT IGNORE
  INTO table_1 
SELECT *
  FROM table_2
     ;

o que permite que essas linhas em table_1 substituam aquelas em table_2 que têm uma chave primária correspondente, enquanto ainda insere linhas com novas chaves primárias.

Alternativamente,

REPLACE
   INTO table_1
 SELECT *
   FROM table_2
      ;

irá atualizar essas linhas já na tabela_1 com a linha correspondente da tabela_2, enquanto insere linhas com novas chaves primárias.

fcw
fonte
2
Na verdade, ele SUBSTITUIRÁ as linhas existentes (excluir + inserir), não atualizará.
Cees Timmerman
e se houver alguma chave estrangeira usada para a tabela 2 ????? Como você atualizará isso?
Kshitiz
39

Depende da semântica da chave primária. Se for apenas incremento automático, use algo como:

insert into table1 (all columns except pk)
select all_columns_except_pk 
from table2;

Se PK significa alguma coisa, você precisa encontrar uma maneira de determinar qual registro deve ter prioridade. Você pode criar uma consulta selecionada para localizar duplicatas primeiro (veja a resposta de cpitis ). Em seguida, elimine aqueles que você não deseja manter e use a inserção acima para adicionar os registros que permanecem.

Milan Babuškov
fonte
21
INSERT
INTO    first_table f
SELECT  *
FROM    second_table s
ON DUPLICATE KEY
UPDATE
        s.column1 = DO_WHAT_EVER_MUST_BE_DONE_ON_KEY_CLASH(f.column1)
Quassnoi
fonte
1
Obrigado pela boa ideia. O cmd acima me dá um erro de sintaxe. Mas isso funciona para mim: INSERT INTO first_table SELECT * FROM second_table ON DUPLICATE KEY UPDATE second_table.column1 = DO_WHAT_EVER_MUST_BE_DONE_ON_KEY_CLASH (first_table.column1)
Tapper
Assim como @Tapper, não consegui atribuir um Alias ​​à primeira tabela. Eu conseguiria Syntax error, unexpected IDENT_QUOTED- por meio do MySQL Workbench de qualquer maneira.
blo0p3r
Você poderia fornecer um exemplo de qual comando você digitaria na última linha? Gostaria que o ID aumentasse a partir do maior ID existente na tabela
Elliott B
15

Se você precisar fazer isso manualmente, uma vez:

Primeiro, mescle em uma tabela temporária, com algo como:

create table MERGED as select * from table 1 UNION select * from table 2

Em seguida, identifique as restrições de chave primária com algo como

SELECT COUNT(*), PK from MERGED GROUP BY PK HAVING COUNT(*) > 1

Onde PK é o campo de chave primária ...

Resolva as duplicatas.

Renomeie a tabela.

[editado - colchetes removidos na consulta UNION, que estava causando o erro no comentário abaixo]

Cătălin Pitiș
fonte
quando tento fazer isso, recebo este erro, "ERROR 1064 (42000): Você tem um erro em sua sintaxe SQL; verifique o manual que corresponde à sua versão do servidor MySQL para obter a sintaxe correta para usar próximo a 'UNION select * from actor)' na linha ", por que isso?
jcho360
7

Não é tão complicado quanto parece .... Basta deixar a chave primária duplicada fora de sua consulta .... isso funciona para mim!

INSERT INTO
  Content(
    `status`,
    content_category,
    content_type,
    content_id,
    user_id,
    title,
    description,
    content_file,
    content_url,
    tags,
    create_date,
    edit_date,
    runs
  )
SELECT `status`,
  content_category,
  content_type,
  content_id,
  user_id,
  title,
  description,
  content_file,
  content_url,
  tags,
  create_date,
  edit_date,
  runs
FROM
  Content_Images
Bill Warren
fonte
0

Você poderia escrever um script para atualizar o FK para você .. confira este blog: http://multunus.com/2011/03/how-to-easily-merge-two-identical-mysql-databases/

Eles têm um script inteligente para usar as tabelas information_schema para obter as colunas "id":

SET @db:='id_new'; 

select @max_id:=max(AUTO_INCREMENT) from information_schema.tables;

select concat('update ',table_name,' set ', column_name,' = ',column_name,'+',@max_id,' ; ') from information_schema.columns where table_schema=@db and column_name like '%id' into outfile 'update_ids.sql';

use id_new
source update_ids.sql;
TimoSolo
fonte