¿Cómo puedo fusionar dos tablas MySQL?

92

¿Cómo puedo fusionar dos tablas MySQL que tienen la misma estructura?

Las claves primarias de las dos tablas entrarán en conflicto, así que lo tengo en cuenta.

Steve McLeod
fuente
6
Cuando dice que las PK pueden entrar en conflicto, ¿quiere decir que puede haber filas duplicadas y no desea que se copien, o que necesita asignar una nueva PK a una de ellas porque son filas realmente diferentes a pesar de tener la mismo PK? (otra razón más para usar claves primarias naturales)
Tom H

Respuestas:

123

También puedes probar:

INSERT IGNORE
  INTO table_1 
SELECT *
  FROM table_2
     ;

lo que permite que las filas de table_1 reemplacen a las de table_2 que tienen una clave principal coincidente, mientras que siguen insertando filas con nuevas claves primarias.

Alternativamente,

REPLACE
   INTO table_1
 SELECT *
   FROM table_2
      ;

actualizará esas filas que ya están en table_1 con la fila correspondiente de table_2, mientras inserta filas con nuevas claves primarias.

fcw
fuente
2
En realidad, REEMPLAZARÁ las filas existentes (eliminar + insertar), no actualizar.
Cees Timmerman
¿qué pasa si se utiliza alguna clave externa para la tabla 2 ????? ¿Cómo actualizará eso?
Kshitiz
39

Depende de la semántica de la clave primaria. Si es solo autoincremento, entonces use algo como:

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

Si PK significa algo, debe encontrar una manera de determinar qué registro debe tener prioridad. Puede crear una consulta de selección para buscar duplicados primero (consulte la respuesta de cpitis ). Luego, elimine los que no desea conservar y use el inserto anterior para agregar los registros que quedan.

Milán Babuškov
fuente
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
fuente
1
Gracias por la buena idea. Sin embargo, el cmd anterior me da un error de sintaxis. Pero esto funciona para mí: 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
Al igual que @Tapper, no pude asignar un Alias ​​a la primera tabla. Lo conseguiría Syntax error, unexpected IDENT_QUOTED- a través de MySQL Workbench de todos modos.
blo0p3r
¿Podría dar un ejemplo de qué comando ingresaría en la última línea? Me gustaría que la identificación aumente desde la identificación existente más alta en la tabla
Elliott B
15

Si necesita hacerlo manualmente, una vez:

Primero, fusione en una tabla temporal, con algo como:

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

Luego, identifique las restricciones de clave primaria con algo como

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

Donde PK es el campo de clave principal ...

Resuelve los duplicados.

Cambie el nombre de la tabla.

[editado: se quitaron los corchetes en la consulta UNION, que estaba causando el error en el comentario a continuación]

Cătălin Pitiș
fuente
cuando intenté esto, recibí este error, "ERROR 1064 (42000): Tiene un error en su sintaxis SQL; consulte el manual que corresponde a la versión de su servidor MySQL para ver la sintaxis correcta para usar cerca de 'UNION select * from actor)' at line ", ¿por qué?
jcho360
7

No es tan complicado como parece ... Simplemente deje la clave principal duplicada fuera de su consulta ... ¡esto funciona para mí!

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
fuente
0

Podrías escribir un script para actualizar los FK por ti ... echa un vistazo a este blog: http://multunus.com/2011/03/how-to-easily-merge-two-identical-mysql-databases/

Tienen un script inteligente para usar las tablas information_schema para obtener las columnas "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
fuente