INSERT INTO… SELECT dla wszystkich kolumn MySQL

119

Próbuję przenieść stare dane z:

this_table >> this_table_archive

kopiowanie wszystkich kolumn. Próbowałem tego, ale to nie działa:

INSERT INTO this_table_archive (*) VALUES (SELECT * FROM this_table WHERE entry_date < '2011-01-01 00:00:00');

Uwaga: tabele są identyczne i mają idustawiony klucz podstawowy.

Kyle
źródło
1
Zdefiniuj „to nie działa”. Mam coś, co może być podobnym problemem, ale nie mogę powiedzieć, ponieważ nie powiedziałeś, jaki był twój problem!
Wyścigi lekkości na orbicie
Nie jest zepsuty, po prostu nie działa.
Webmaster G

Odpowiedzi:

218

Prawidłowa składnia jest opisana w instrukcji . Spróbuj tego:

INSERT INTO this_table_archive (col1, col2, ..., coln)
SELECT col1, col2, ..., coln
FROM this_table
WHERE entry_date < '2011-01-01 00:00:00';

Jeśli kolumny id są kolumną z automatyczną inkrementacją i masz już jakieś dane w obu tabelach, to w niektórych przypadkach możesz chcieć pominąć identyfikator z listy kolumn i zamiast tego wygenerować nowe identyfikatory, aby uniknąć wstawienia identyfikatora, który już istnieje w oryginale stół. Jeśli twoja tabela docelowa jest pusta, nie będzie to problemem.

Mark Byers
źródło
73

W przypadku składni wygląda to tak (pomiń listę kolumn, aby niejawnie oznaczać „wszystko”)

INSERT INTO this_table_archive
SELECT *
FROM this_table
WHERE entry_date < '2011-01-01 00:00:00'

Aby uniknąć błędów klucza podstawowego, jeśli masz już dane w tabeli archiwum

INSERT INTO this_table_archive
SELECT t.*
FROM this_table t
LEFT JOIN this_table_archive a on a.id=t.id
WHERE t.entry_date < '2011-01-01 00:00:00'
  AND a.id is null  # does not yet exist in archive
RichardTheKiwi
źródło
6
+1 dla lewego sprzężenia, aby uniknąć kolizji klucza podstawowego.
Hartley Brody
23

Dodatek do odpowiedzi Mark Byers:

Czasami chcesz również wstawić zakodowane na stałe szczegóły, w przeciwnym razie może się zdarzyć, że ograniczenie Unique nie powiedzie się itp. Dlatego użyj następujących w sytuacji, gdy nadpisujesz niektóre wartości kolumn.

INSERT INTO matrimony_domain_details (domain, type, logo_path)
SELECT 'www.example.com', type, logo_path
FROM matrimony_domain_details
WHERE id = 367

Tutaj wartość domeny jest dodawana przeze mnie w zakodowany sposób, aby pozbyć się ograniczenia Unique.

Pratik
źródło
4

czy nie potrzebujesz double () dla wartości bit? jeśli nie, spróbuj tego (chociaż musi być lepszy sposób

insert into this_table_archive (id, field_1, field_2, field_3) 
values
((select id from this_table where entry_date < '2001-01-01'), 
((select field_1 from this_table where entry_date < '2001-01-01'), 
((select field_2 from this_table where entry_date < '2001-01-01'), 
((select field_3 from this_table where entry_date < '2001-01-01'));
Daniel Casserly
źródło
2
OP używa INSERT INTO .. SELECT FROM, nie INSERT INTO .. VALUES. Inna funkcja.
Wyścigi lekkości na orbicie
0

Więcej przykładów i szczegółów

    INSERT INTO vendors (
     name, 
     phone, 
     addressLine1,
     addressLine2,
     city,
     state,
     postalCode,
     country,
     customer_id
 )
 SELECT 
     name,
     phone,
     addressLine1,
     addressLine2,
     city,
     state ,
     postalCode,
     country,
     customer_id
 FROM 
     customers;
Deweloper
źródło