Kiedy mówisz, że PK mogą się ze sobą kolidować, czy masz na myśli to, że mogą istnieć zduplikowane wiersze i nie chcesz ich kopiować, lub że musisz przypisać nowy PK do jednego z nich, ponieważ są naprawdę różnymi wierszami pomimo posiadania ten sam PK? (kolejny powód, aby używać naturalnych kluczy głównych)
Tom H
Odpowiedzi:
124
Możesz też spróbować:
INSERTIGNOREINTO table_1
SELECT *
FROM table_2
;
co pozwala tym wierszom w tabeli_1 zastąpić wiersze w tabeli_2, które mają zgodny klucz podstawowy, jednocześnie wstawiając wiersze z nowymi kluczami podstawowymi.
Alternatywnie,
REPLACEINTO table_1
SELECT *
FROM table_2
;
zaktualizuje te wiersze już w tabeli_1 o odpowiadające im wiersze z tabeli_2, podczas wstawiania wierszy z nowymi kluczami podstawowymi.
W rzeczywistości ZMIENI istniejące wiersze (usuń + wstaw), a nie zaktualizuje.
Cees Timmerman
a co jeśli jest jakiś klucz obcy używany w tabeli 2 ????? Jak to zaktualizujesz?
Kshitiz
39
Zależy to od semantyki klucza podstawowego. Jeśli to tylko autoinkrementacja, użyj czegoś takiego:
insertinto table1 (allcolumnsexcept pk)
select all_columns_except_pk
from table2;
Jeśli PK coś znaczy, musisz znaleźć sposób na określenie, który rekord powinien mieć priorytet. Możesz utworzyć zapytanie wybierające, aby najpierw znaleźć duplikaty (patrz odpowiedź według cpitis ). Następnie usuń te, których nie chcesz zachować i użyj powyższej wstawki, aby dodać pozostałe rekordy.
Dzięki za dobry pomysł. Powyższe cmd powoduje jednak błąd składniowy. Ale to działa dla mnie: 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
Podobnie jak @Tapper, nie mogłem przypisać aliasu do pierwszej tabeli. Chciałbym dostać Syntax error, unexpected IDENT_QUOTED- przez MySQL Workbench jakikolwiek.
blo0p3r
Czy możesz podać przykład polecenia, które wpisałeś w ostatnim wierszu? Chciałbym, aby identyfikator wzrastał z najwyższego istniejącego identyfikatora w tabeli
kiedy próbuję tego, otrzymałem ten błąd: „BŁĄD 1064 (42000): Masz błąd w składni SQL; sprawdź instrukcję, która odpowiada Twojej wersji serwera MySQL, aby znaleźć właściwą składnię w pobliżu„ UNION select * from actor) ” na linii ”, dlaczego tak jest?
jcho360
7
Nie jest to tak skomplikowane, jak się wydaje ... Po prostu pozostaw zduplikowany klucz podstawowy poza swoim zapytaniem ... to działa dla mnie!
Mają sprytny skrypt, który wykorzystuje tabele information_schema do pobierania kolumn „id”:
SET @db:='id_new';
select @max_id:=max(AUTO_INCREMENT) from information_schema.tables;
selectconcat('update ',table_name,' set ', column_name,' = ',column_name,'+',@max_id,' ; ') from information_schema.columns where table_schema=@db and column_name like'%id'intooutfile'update_ids.sql';
use id_new
source update_ids.sql;
Odpowiedzi:
Możesz też spróbować:
INSERT IGNORE INTO table_1 SELECT * FROM table_2 ;
co pozwala tym wierszom w tabeli_1 zastąpić wiersze w tabeli_2, które mają zgodny klucz podstawowy, jednocześnie wstawiając wiersze z nowymi kluczami podstawowymi.
Alternatywnie,
REPLACE INTO table_1 SELECT * FROM table_2 ;
zaktualizuje te wiersze już w tabeli_1 o odpowiadające im wiersze z tabeli_2, podczas wstawiania wierszy z nowymi kluczami podstawowymi.
źródło
Zależy to od semantyki klucza podstawowego. Jeśli to tylko autoinkrementacja, użyj czegoś takiego:
insert into table1 (all columns except pk) select all_columns_except_pk from table2;
Jeśli PK coś znaczy, musisz znaleźć sposób na określenie, który rekord powinien mieć priorytet. Możesz utworzyć zapytanie wybierające, aby najpierw znaleźć duplikaty (patrz odpowiedź według cpitis ). Następnie usuń te, których nie chcesz zachować i użyj powyższej wstawki, aby dodać pozostałe rekordy.
źródło
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)
źródło
Syntax error, unexpected IDENT_QUOTED
- przez MySQL Workbench jakikolwiek.Jeśli musisz to zrobić ręcznie, jednorazowo:
Najpierw połącz tabelę tymczasową z czymś takim:
create table MERGED as select * from table 1 UNION select * from table 2
Następnie zidentyfikuj ograniczenia klucza podstawowego za pomocą czegoś takiego jak
SELECT COUNT(*), PK from MERGED GROUP BY PK HAVING COUNT(*) > 1
Gdzie PK to pole klucza podstawowego ...
Rozwiąż duplikaty.
Zmień nazwę tabeli.
[edytowano - usunięto nawiasy w zapytaniu UNION, które powodowały błąd w komentarzu poniżej]
źródło
Nie jest to tak skomplikowane, jak się wydaje ... Po prostu pozostaw zduplikowany klucz podstawowy poza swoim zapytaniem ... to działa dla mnie!
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
źródło
Możesz napisać skrypt, który zaktualizuje dla Ciebie FK. Zajrzyj na tego bloga: http://multunus.com/2011/03/how-to-easily-merge-two-identical-mysql-databases/
Mają sprytny skrypt, który wykorzystuje tabele information_schema do pobierania kolumn „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;
źródło