Как я могу объединить две таблицы MySQL?


94

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

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


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

Ответы:


124

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

INSERT IGNORE
  INTO table_1 
SELECT *
  FROM table_2
     ;

который позволяет тем строкам в таблице_1 заменять те строки в таблице_2, которые имеют соответствующий первичный ключ, при этом вставляя строки с новыми первичными ключами.

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

REPLACE
   INTO table_1
 SELECT *
   FROM table_2
      ;

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


2
Фактически, он будет ЗАМЕНИТЬ существующие строки (удалить + вставить), а не обновить.
Cees Timmerman

как насчет того, используется ли какой-либо внешний ключ для таблицы 2 ????? Как то обновишь?
Кшитиз 05

39

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

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

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


22
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 ON DUPLICATE KEY UPDATE second_table.column1 = DO_WHAT_EVER_MUST_BE_DONE_ON_KEY_CLASH (first_table.column1)
Tapper

Как и @Tapper, я не мог назначить псевдоним первой таблице. Я бы все равно получил Syntax error, unexpected IDENT_QUOTED- через MySQL Workbench.
blo0p3r

Не могли бы вы привести пример того, какую команду вы бы вводили в последней строке? Я бы хотел, чтобы идентификатор увеличивался с самого высокого существующего идентификатора в таблице
Elliott B

15

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

Сначала слейте во временную таблицу что-то вроде:

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 - это поле первичного ключа ...

Решите дубликаты.

Переименуйте таблицу.

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


когда я попробовал это, я получил эту ошибку: «ОШИБКА 1064 (42000): у вас есть ошибка в синтаксисе SQL; проверьте руководство, которое соответствует вашей версии сервера MySQL, чтобы найти правильный синтаксис рядом с 'UNION select * from субъектом)' в строке ", почему?
jcho360

7

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

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

Вы могли бы написать сценарий для обновления 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 table_schema=@db and column_name like '%id' into outfile 'update_ids.sql';

use id_new
source update_ids.sql;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.