İki MySQL tablosunu nasıl birleştirebilirim?


94

Aynı yapıya sahip iki MySQL tablosunu nasıl birleştirebilirim?

İki tablonun birincil anahtarları çakışacak, bu yüzden bunu dikkate aldım.


6
PK'lerin çakışabileceğini söylediğinizde, yinelenen satırlar olabileceğini ve bunların kopyalanmasını istemediğinizi veya bunlardan birine yeni bir PK atamanız gerektiğini, çünkü bunlardan birine sahip olmasına rağmen gerçekten farklı satırlar olduğunu mu kastediyorsunuz? aynı PK? (yine de doğal birincil anahtarları kullanmak için başka bir neden)
Tom H

Yanıtlar:


124

Şunları da deneyebilirsiniz:

INSERT IGNORE
  INTO table_1 
SELECT *
  FROM table_2
     ;

Bu, yeni birincil anahtarların bulunduğu satırları eklemeye devam ederken, tablo_1'deki satırların tablo_2'de eşleşen birincil anahtara sahip olanların yerini almasına olanak tanır.

Alternatif olarak,

REPLACE
   INTO table_1
 SELECT *
   FROM table_2
      ;

yeni birincil anahtarların bulunduğu satırları eklerken, zaten tablo_1'de bulunan satırları tablo_2'deki karşılık gelen satırla günceller.


2
Aslında, güncelleme değil, mevcut satırları DEĞİŞTİRECEK (sil + ekle).
Cees Timmerman

peki tablo 2 için kullanılan herhangi bir yabancı anahtar varsa ????? Bunu nasıl güncelleyeceksin?
Kshitiz

39

Birincil anahtarın anlamsallığına bağlıdır. Yalnızca otomatik artış ise, aşağıdaki gibi bir şey kullanın:

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

PK bir şey ifade ediyorsa, hangi kaydın öncelikli olması gerektiğini belirlemenin bir yolunu bulmanız gerekir. Önce kopyaları bulmak için bir seçme sorgusu oluşturabilirsiniz ( cpitis tarafından verilen cevaba bakın ). Ardından, saklamak istemediklerinizi eleyin ve kalan kayıtları eklemek için yukarıdaki eki kullanın.


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
İyi fikir için teşekkürler. Yukarıdaki cmd bana bir sözdizimi hatası veriyor. Ama bu benim için çalışıyor: 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

Tıpkı @Tapper gibi, ilk tabloya bir Alias ​​atayamadım. Ben alacağı Syntax error, unexpected IDENT_QUOTED- MySQL Workbench aracılığıyla neyse.
blo0p3r

Son satıra hangi komutu gireceğinize bir örnek verebilir misiniz? Kimliğin tablodaki en yüksek mevcut
Elliott B

15

Manuel olarak yapmanız gerekiyorsa, bir kez:

İlk olarak, aşağıdaki gibi geçici bir tabloda birleştirin:

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

Ardından, birincil anahtar kısıtlamalarını aşağıdaki gibi tanımlayın:

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

PK birincil anahtar alanı olduğunda ...

Yinelenenleri çözün.

Tabloyu yeniden adlandırın.

[düzenlendi - UNION sorgusundaki kaldırılan parantezler aşağıdaki yorumda hataya neden oluyordu]


bunu denediğimde şu hatayı aldım, "ERROR 1064 (42000): SQL sözdiziminizde bir hata var; doğru sözdizimi için MySQL sunucu sürümünüze karşılık gelen kılavuza bakın 'UNION select * from actor)' satırda ", bu neden?
jcho360

7

Göründüğü kadar karmaşık değil .... Yinelenen birincil anahtarı sorgunuzun dışında bırakın ... bu benim için çalışıyor!

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'leri sizin için güncellemek için bir komut dosyası yazabilirsiniz .. bu bloga göz atın: http://multunus.com/2011/03/how-to-easily-merge-two-identical-mysql-databases/

"İd" sütunlarını almak için bilgi şeması tablolarını kullanmak üzere akıllı bir komut dosyasına sahipler:

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;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.