¿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.


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.


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.


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)

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]


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

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;
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.