2009-04-07 2 views
79

Как слить две таблицы MySQL, которые имеют одинаковую структуру?Как слить две таблицы MySQL?

Первичные ключи двух таблиц столкнутся, поэтому я учитываю это.

+6

Когда вы говорите, что PKs может столкнуться, вы имеете в виду, что там могут быть повторяющиеся строки, и вы не хотите их копировать, или что вам нужно назначить новый ПК к одному из них, потому что они действительно разные ряды, несмотря на то, что у них такой же ПК?(еще одна причина использовать естественные первичные ключи) –

ответ

105

Вы также можете попробовать:

INSERT IGNORE 
    INTO table_1 
SELECT * 
    FROM table_2 
    ; 

, который позволяет эти строки в table_1 вытеснять те, в table_2, которые имеют соответствующий первичный ключ, в то же время вставки строки с новыми первичными ключами.

В качестве альтернативы,

REPLACE 
    INTO table_1 
SELECT * 
    FROM table_2 
     ; 

будет обновлять эти строки уже table_1 с соответствующей строкой из table_2, при вставке строк с новыми первичными ключами.

+2

Может ли это быть из многих таблиц? – SaidbakR

+1

Фактически это будет [ЗАМЕНИТЬ] (http://code.openark.org/blog/mysql/replace-into-think-twice) существующие строки (удалить + вставить), а не обновлять. –

13

Если вам нужно сделать это вручную, один раз:

Во-первых, слияние во временной таблице, с чем-то вроде:

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

Затем определить ограничения первичного ключа что-то вроде

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

Где PK является первичным ключом ...

Решите DUPL icates.

Переименовать стол.

[отредактированные - удалены скобки в запросе UNION, который вызывает ошибку в комментарии ниже]

+0

при попытке этого я получил эту ошибку: «ERROR 1064 (42000): у вас возникла ошибка в синтаксисе SQL, проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса использовать рядом с UNION select * от актера) «на линии», почему? – 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

Спасибо за хорошую идею. Однако приведенный выше cmd дает мне синтаксическую ошибку. Но это работает для меня: INSERT INTO first_table SELECT * FROM second_table дублированием KEY UPDATE second_table.column1 = DO_WHAT_EVER_MUST_BE_DONE_ON_KEY_CLASH (first_table.column1) – Tapper

+0

Как @Tapper, я не мог присвоить псевдоним к первому Таблица. Я бы получил «Синтаксическую ошибку, неожиданную IDENT_QUOTED» - через MySQL Workbench. – blo0p3r

35

Это зависит от семантики первичного ключа. Если это просто Autoincrement, а затем использовать что-то вроде:

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

Если PK означает что-то, что вам нужно найти способ, чтобы определить, какие записи должны иметь приоритет. Вы можете создать запрос выбора, чтобы сначала найти дубликаты (см. answer by cpitis). Затем устраните те, которые вы не хотите хранить, и используйте приведенную выше вставку, чтобы добавить оставшиеся записи.

0

Вы могли бы написать сценарий, чтобы обновить FK для вас .. проверить этот блог: http://multunus.com/2011/03/how-to-easily-merge-two-identical-mysql-databases/

Они имеют умный сценарий, чтобы использовать таблицы information_schema, чтобы получить «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 [email protected] and column_name like '%id' into outfile 'update_ids.sql'; 

use id_new 
source update_ids.sql; 
5

Не так сложно, как кажется ... Просто оставьте дублирующий первичный ключ из вашего запроса .... это работает для меня!

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