INSERT INTO… SELECT pour toutes les colonnes MySQL

119

J'essaye de déplacer d'anciennes données de:

this_table >> this_table_archive

copie de toutes les colonnes. J'ai essayé ceci, mais cela ne fonctionne pas:

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

Remarque: les tables sont identiques et ont été iddéfinies comme clé primaire.

Kyle
la source
1
Définissez "ça ne marche pas". J'ai ce qui peut être un problème similaire mais je ne peux pas le dire car vous n'avez pas dit quel était votre problème !!
Courses de légèreté en orbite
Ce n'est pas cassé, ça ne marche tout simplement pas.
Webmaster G

Réponses:

218

La syntaxe correcte est décrite dans le manuel . Essaye ça:

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

Si les colonnes id sont une colonne à incrémentation automatique et que vous avez déjà des données dans les deux tables, vous pouvez dans certains cas vouloir omettre l'id de la liste des colonnes et générer de nouveaux identifiants à la place pour éviter d'insérer un identifiant qui existe déjà dans l'original table. Si votre table cible est vide, ce ne sera pas un problème.

Mark Byers
la source
73

Pour la syntaxe, cela ressemble à ceci (laissez de côté la liste des colonnes pour signifier implicitement "tout")

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

Pour éviter les erreurs de clé primaire si vous avez déjà des données dans la table d'archivage

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
la source
6
+1 pour la jointure gauche pour éviter les collisions de clé primaire.
Hartley Brody
23

Ajout à la réponse de Mark Byers:

Parfois, vous souhaitez également insérer des détails codés en dur, sinon il peut y avoir un échec de contrainte unique, etc.

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

Ici , la valeur de domaine est ajoutée par moi-même de manière codée en dur pour se débarrasser de la contrainte unique.

Pratik
la source
4

n'avez-vous pas besoin de double () pour le bit de valeurs? sinon essayez ceci (bien qu'il doit y avoir un meilleur moyen

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
la source
2
L'OP utilise INSERT INTO .. SELECT FROM, non INSERT INTO .. VALUES. Caractéristique différente.
Courses de légèreté en orbite
0

Plus d'exemples et de détails

    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;
Développeur
la source