INSERT INTO ... SELECT для всех столбцов MySQL - PullRequest
112 голосов
/ 10 марта 2011

Я пытаюсь переместить старые данные из:

this_table >> this_table_archive

, копируя все столбцы.Я пробовал это, но это не работает:

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

Примечание: таблицы идентичны и в качестве первичного ключа установлены id.

Ответы [ 5 ]

208 голосов
/ 10 марта 2011

Правильный синтаксис описан в руководстве . Попробуйте это:

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

Если столбцы идентификаторов - это столбец с автоинкрементом, и у вас уже есть данные в обеих таблицах, то в некоторых случаях вы можете опустить идентификатор из списка столбцов и сгенерировать новые идентификаторы, чтобы избежать вставки уже существующего идентификатора. в оригинальной таблице. Если ваша целевая таблица пуста, это не будет проблемой.

62 голосов
/ 10 марта 2011

Для синтаксиса это выглядит следующим образом (пропустите список столбцов, чтобы неявно означать «все»)

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

Чтобы избежать ошибок первичного ключа, если у вас уже есть данные в таблице архива

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
20 голосов
/ 07 декабря 2015

Дополнение к ответу Марка Байерса:

Иногда вы также хотите вставить Жестко закодированные подробности, в противном случае может быть уникальное ограничение и т.д.

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

Здесь домен значение добавлено мной в жестком коде, чтобы избавиться от уникального ограничения.

4 голосов
/ 10 марта 2011

вам не нужно double () для значений бит?если нет, попробуйте это (хотя должен быть лучший способ

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'));
0 голосов
/ 18 июня 2019

Дополнительные примеры и подробности

    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;
...