INSERT INTO… SELECT для всех столбцов MySQL


119

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

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в качестве первичного ключа.


1
Дайте определение «не работает». У меня может быть похожая проблема, но я не могу сказать, потому что вы не сказали, в чем была ваша проблема !!
Lightness Races на орбите

Не сломано, просто не работает.
Webmaster G

Ответы:


218

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

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

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


73

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

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

6
+1 для левого соединения, чтобы избежать конфликтов первичных ключей.
Хартли Броуди,

23

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

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

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

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


4

вам не нужен 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'));

2
OP использует INSERT INTO .. SELECT FROM, а не INSERT INTO .. VALUES. Отличная особенность.
Lightness Races на орбите

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.