Wie kann ich zwei MySQL-Tabellen zusammenführen?

92

Wie kann ich zwei MySQL-Tabellen mit derselben Struktur zusammenführen?

Die Primärschlüssel der beiden Tabellen werden zusammenstoßen, daher habe ich dies berücksichtigt.

Steve McLeod
quelle
6
Wenn Sie sagen, dass die PKs möglicherweise kollidieren, meinen Sie damit, dass möglicherweise doppelte Zeilen vorhanden sind und Sie nicht möchten, dass sie kopiert werden, oder dass Sie einer von ihnen eine neue PK zuweisen müssen, da sie trotz der Zeilen wirklich unterschiedliche Zeilen haben gleiche PK? (Ein weiterer Grund, natürliche Primärschlüssel zu verwenden)
Tom H

Antworten:

123

Sie können auch versuchen:

INSERT IGNORE
  INTO table_1 
SELECT *
  FROM table_2
     ;

Dadurch können die Zeilen in Tabelle_1 die Zeilen in Tabelle_2 ersetzen, die einen passenden Primärschlüssel haben, während weiterhin Zeilen mit neuen Primärschlüsseln eingefügt werden.

Alternative,

REPLACE
   INTO table_1
 SELECT *
   FROM table_2
      ;

aktualisiert die bereits in Tabelle_1 enthaltenen Zeilen mit der entsprechenden Zeile aus Tabelle_2, während Zeilen mit neuen Primärschlüsseln eingefügt werden.

fcw
quelle
2
Eigentlich wird es REPLACE vorhandene Zeilen (delete + Insert), nicht aktualisieren.
Cees Timmerman
Was ist, wenn für Tabelle 2 ein Fremdschlüssel verwendet wird? Wie werden Sie das aktualisieren?
Kshitiz
39

Dies hängt von der Semantik des Primärschlüssels ab. Wenn es sich nur um eine automatische Inkrementierung handelt, verwenden Sie Folgendes:

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

Wenn PK etwas bedeutet, müssen Sie einen Weg finden, um zu bestimmen, welcher Datensatz Priorität haben soll. Sie können eine Auswahlabfrage erstellen, um zuerst Duplikate zu finden (siehe Antwort von cpitis ). Entfernen Sie dann diejenigen, die Sie nicht behalten möchten, und verwenden Sie die obige Einfügung, um verbleibende Datensätze hinzuzufügen.

Milan Babuškov
quelle
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
quelle
1
Danke für die gute Idee. Das obige cmd gibt mir jedoch einen Syntaxfehler. Aber das funktioniert bei mir: 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
Genau wie bei @Tapper konnte ich der ersten Tabelle keinen Alias ​​zuweisen. Ich würde Syntax error, unexpected IDENT_QUOTEDsowieso durch MySQL Workbench kommen.
blo0p3r
Können Sie ein Beispiel dafür geben, welchen Befehl Sie in der letzten Zeile eingeben würden? Ich möchte, dass die ID von der höchsten vorhandenen ID in der Tabelle erhöht wird
Elliott B
15

Wenn Sie dies einmal manuell tun müssen:

Führen Sie zunächst eine temporäre Tabelle mit folgenden Elementen zusammen:

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

Identifizieren Sie dann die Primärschlüsseleinschränkungen mit etwas wie

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

Wobei PK das Primärschlüsselfeld ist ...

Löse die Duplikate.

Benennen Sie die Tabelle um.

[bearbeitet - Klammern in der UNION-Abfrage entfernt, was den Fehler im Kommentar unten verursacht hat]

Cătălin Pitiș
quelle
Als ich dies versuchte, erhielt ich den Fehler "FEHLER 1064 (42000): Sie haben einen Fehler in Ihrer SQL-Syntax. Überprüfen Sie das Handbuch, das Ihrer MySQL-Serverversion entspricht, auf die richtige Syntax für die Verwendung in der Nähe von 'UNION select * from Actor'." at line ", warum ist das so?
jcho360
7

Nicht so kompliziert, wie es sich anhört ... Lassen Sie einfach den doppelten Primärschlüssel aus Ihrer Abfrage heraus ... das funktioniert bei mir!

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

Sie könnten ein Skript schreiben, um die FKs für Sie zu aktualisieren. Schauen Sie sich diesen Blog an: http://multunus.com/2011/03/how-to-easily-merge-two-identical-mysql-databases/

Sie haben ein cleveres Skript, um mithilfe der information_schema-Tabellen die "id" -Spalten abzurufen:

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
quelle