INSERT INTO… SELECT für alle MySQL-Spalten

119

Ich versuche, alte Daten zu verschieben von:

this_table >> this_table_archive

Kopieren aller Spalten. Ich habe es versucht, aber es funktioniert nicht:

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

Hinweis: Die Tabellen sind identisch und wurden idals Primärschlüssel festgelegt.

Kyle
quelle
1
Definieren Sie "es funktioniert nicht". Ich habe ein ähnliches Problem, aber ich kann es nicht sagen, weil Sie nicht gesagt haben, was Ihr Problem war !!
Leichtigkeitsrennen im Orbit
Es ist nicht kaputt, es funktioniert einfach nicht.
Webmaster G

Antworten:

218

Die korrekte Syntax ist im Handbuch beschrieben . Versuche dies:

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

Wenn es sich bei den ID-Spalten um eine Spalte mit automatischer Inkrementierung handelt und Sie bereits einige Daten in beiden Tabellen haben, möchten Sie in einigen Fällen möglicherweise die ID aus der Spaltenliste weglassen und stattdessen neue IDs generieren, um zu vermeiden, dass eine ID eingefügt wird, die bereits im Original vorhanden ist Tabelle. Wenn Ihre Zieltabelle leer ist, ist dies kein Problem.

Mark Byers
quelle
72

Für die Syntax sieht es so aus (lassen Sie die Spaltenliste weg, um implizit "alle" zu bedeuten)

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

Zur Vermeidung von Primärschlüsselfehlern, wenn Sie bereits Daten in der Archivtabelle haben

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
quelle
6
+1 für die linke Verknüpfung, um Kollisionen mit Primärschlüsseln zu vermeiden.
Hartley Brody
22

Ergänzung zu Mark Byers Antwort:

Manchmal möchten Sie auch fest codierte Details einfügen, da sonst möglicherweise ein eindeutiger Einschränkungsfehler usw. auftritt. Verwenden Sie daher in solchen Situationen, in denen Sie einige Werte der Spalten überschreiben, Folgendes.

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

Hier wird der Domain- Wert von mir auf fest codierte Weise hinzugefügt, um die eindeutige Einschränkung zu beseitigen.

Pratik
quelle
4

Benötigen Sie nicht double () für das Wertebit? Wenn nicht, versuchen Sie dies (obwohl es einen besseren Weg geben muss

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
quelle
2
Das OP verwendet INSERT INTO .. SELECT FROMnicht INSERT INTO .. VALUES. Andere Funktion.
Leichtigkeitsrennen im Orbit
0

Weitere Beispiele & Details

    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;
Entwickler
quelle