120

I'm trying to move old data from:

this_table >> this_table_archive

copying all columns over. I've tried this, but it doesn't work:

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

Note: the tables are identical and have id set as a primary key.

shgnInc
  • 2,054
  • 1
  • 23
  • 34
Kyle Cureau
  • 19,028
  • 23
  • 75
  • 104
  • 1
    Define "it doesn't work". I am having what may be a similar problem but I can't tell because you didn't say what your problem was!! – Lightness Races in Orbit Jul 30 '15 at 15:59
  • 1
    It's not broken, it just doesn't work. – Webmaster G Sep 08 '17 at 20:52
  • See also here [https://stackoverflow.com/questions/3709560/joining-three-tables-using-mysql](https://stackoverflow.com/questions/3709560/joining-three-tables-using-mysql) –  Oct 11 '17 at 23:14

4 Answers4

219

The correct syntax is described in the manual. Try this:

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

If the id columns is an auto-increment column and you already have some data in both tables then in some cases you may want to omit the id from the column list and generate new ids instead to avoid insert an id that already exists in the original table. If your target table is empty then this won't be an issue.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
80

For the syntax, it looks like this (leave out the column list to implicitly mean "all")

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

For avoiding primary key errors if you already have data in the archive table

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
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
RichardTheKiwi
  • 105,798
  • 26
  • 196
  • 262
23

Addition to Mark Byers answer :

Sometimes you also want to insert Hardcoded details else there may be Unique constraint fail etc. So use following in such situation where you override some values of the columns.

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

Here domain value is added by me me in Hardcoded way to get rid from Unique constraint.

Pratik Joshi
  • 11,485
  • 7
  • 41
  • 73
4

don't you need double () for the values bit? if not try this (although there must be a better way

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'));
vidit
  • 6,293
  • 3
  • 32
  • 50
Daniel Casserly
  • 3,552
  • 2
  • 29
  • 60