Come posso unire due tabelle MySQL?


92

Come posso unire due tabelle MySQL che hanno la stessa struttura?

Le chiavi primarie delle due tabelle si scontreranno, quindi devo tenerne conto.


6
Quando dici che i PK potrebbero entrare in conflitto, intendi che potrebbero esserci righe duplicate e non vuoi che vengano copiate, o che devi assegnare un nuovo PK a uno di essi perché sono righe davvero diverse nonostante abbiano il stesso PK? (ancora un altro motivo per usare le chiavi primarie naturali)
Tom H

Risposte:


123

Puoi anche provare:

INSERT IGNORE
  INTO table_1 
SELECT *
  FROM table_2
     ;

che consente alle righe della tabella_1 di sostituire quelle della tabella_2 che hanno una chiave primaria corrispondente, pur inserendo righe con nuove chiavi primarie.

In alternativa,

REPLACE
   INTO table_1
 SELECT *
   FROM table_2
      ;

aggiornerà quelle righe già nella tabella_1 con la riga corrispondente dalla tabella_2, inserendo righe con nuove chiavi primarie.


2
In realtà, SOSTITUIRÀ le righe esistenti (elimina + inserisci), non aggiornerà.
Cees Timmerman,

che dire se è stata utilizzata una chiave esterna per la tabella 2 ????? Come lo aggiornerete?
Kshitiz

39

Dipende dalla semantica della chiave primaria. Se è solo autoincremento, usa qualcosa come:

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

Se PK significa qualcosa, devi trovare un modo per determinare quale record dovrebbe avere la priorità. È possibile creare una query di selezione per trovare prima i duplicati (vedere la risposta di cpitis ). Quindi eliminare quelli che non si desidera conservare e utilizzare l'inserto sopra per aggiungere i record che rimangono.


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
Grazie per la buona idea. Il cmd sopra mi dà però un errore di sintassi. Ma questo funziona per me: 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

Proprio come @Tapper, non sono riuscito ad assegnare un alias alla prima tabella. Avrei Syntax error, unexpected IDENT_QUOTEDcomunque - tramite MySQL Workbench.
blo0p3r

Potresti fornire un esempio di quale comando inseriresti nell'ultima riga? Vorrei che l'ID aumentasse dall'ID più alto esistente nella tabella
Elliott B

15

Se devi farlo manualmente, una volta:

Innanzitutto, unisci in una tabella temporanea, con qualcosa di simile:

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

Quindi, identifica i vincoli della chiave primaria con qualcosa di simile

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

Dove PK è il campo chiave primaria ...

Risolvi i duplicati.

Rinomina la tabella.

[modificato - parentesi graffe rimosse nella query UNION, che causava l'errore nel commento sotto]


quando provo, ho ricevuto questo errore, "ERRORE 1064 (42000): Hai un errore nella sintassi SQL; controlla il manuale che corrisponde alla versione del tuo server MySQL per la sintassi corretta da usare vicino a" UNION select * from actor) " in linea ", perché?
jcho360

7

Non è così complicato come sembra .... Basta lasciare la chiave primaria duplicata fuori dalla tua query ... questo funziona per me!

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

Potresti scrivere uno script per aggiornare gli FK per te .. dai un'occhiata a questo blog: http://multunus.com/2011/03/how-to-easily-merge-two-identical-mysql-databases/

Hanno uno script intelligente per utilizzare le tabelle information_schema per ottenere le colonne "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;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.