2009-04-07 19 views
79

Wie kann ich zwei MySQL-Tabellen zusammenführen, die dieselbe Struktur haben?Wie kann ich zwei MySQL-Tabellen zusammenführen?

Die Primärschlüssel der beiden Tabellen werden kollidieren, also muss ich das berücksichtigen.

+6

Wenn Sie sagen, dass die PKs kollidieren könnten, tun Sie bedeuten, dass es doppelte Zeilen sein könnte, und Sie wollen sie nicht kopiert, oder dass Sie eine neue PK zu einem von ihnen zugewiesen werden müssen, weil sie wirklich unterschiedliche Reihen trotz gleicher PK?(Noch ein weiterer Grund, natürliche Primärschlüssel zu verwenden) –

Antwort

105

Sie können auch versuchen:

INSERT IGNORE 
    INTO table_1 
SELECT * 
    FROM table_2 
    ; 

, die die Zeilen in table_1 erlaubt jene in table_2, die haben einen passenden Primärschlüssel, während nach wie vor Einfügen von Zeilen mit neuen Primärschlüssel zu ersetzen. Alternativ

,

REPLACE 
    INTO table_1 
SELECT * 
    FROM table_2 
     ; 

werden die Zeilen bereits in table_1 mit der entsprechenden Reihe von table_2 aktualisieren, während Reihen mit neuen Primärschlüssel eingefügt wird.

+2

könnte es von vielen Tabellen sein? – SaidbakR

+1

Tatsächlich wird es [REPLACE] (http://code.openark.org/blog/mysql/replace-into-think-twice) vorhandene Zeilen (löschen + einfügen), nicht aktualisieren. –

13

Wenn Sie es manuell tun müssen, einmal:

Zunächst verschmelzen in einer temporären Tabelle, mit so etwas wie:

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

Dann identifizieren die Primärschlüssel mit so etwas wie

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

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

Löst das dupl icates.

Benennen Sie die Tabelle um.

[bearbeitet - entfernt Klammern in der UNION-Abfrage, die den Fehler in dem Kommentar unten verursacht wurde]

+0

Wenn ich dies versuche, habe ich diesen Fehler erhalten, "FEHLER 1064 (42000): Sie haben einen Fehler in Ihrer SQL-Syntax; überprüfen Sie das Handbuch, das Ihrer MySQL-Serverversion für die richtige Syntax entspricht in der Nähe 'UNION select * from actor)' at line 'zu benutzen, warum ist das so? – jcho360

19
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

Danke für die gute Idee. Der obige Befehl gibt mir einen Syntaxfehler. Aber das funktioniert für mich: 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

+0

Genau wie @Tapper, konnte ich nicht bekommen einen Alias ​​mit dem ersten zuweisen Tabelle. Ich würde "Syntaxfehler, unerwartete IDENT_QUOTED" - durch MySQL Workbench sowieso bekommen. – blo0p3r

35

Es hängt von der Semantik des Primärschlüssels. Wenn es nur autoincrement ist, dann so etwas wie verwenden:

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 sollte. Sie könnten eine Auswahlabfrage erstellen, um zuerst Duplikate zu finden (siehe answer by cpitis). Dann eliminieren Sie diejenigen, die Sie nicht behalten möchten, und verwenden Sie die obige Einfügung, um noch vorhandene Datensätze hinzuzufügen.

0

Sie ein Skript schreiben, könnte der FK ist für Sie .. lesen Sie in diesem Blog zu aktualisieren: http://multunus.com/2011/03/how-to-easily-merge-two-identical-mysql-databases/

Sie haben eine clevere Skript die information_schema Tabellen zu verwenden, um die „id“ Spalten zu erhalten:

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 [email protected] and column_name like '%id' into outfile 'update_ids.sql'; 

use id_new 
source update_ids.sql; 
5

Nicht so kompliziert wie es klingt .... Lassen Sie einfach den doppelten Primärschlüssel aus Ihrer Abfrage .... dies funktioniert für mich!

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 
Verwandte Themen