Дублировать / копировать записи в одной таблице MySQL

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

У меня есть этот запрос:

INSERT INTO invoices SELECT * FROM invoices AS iv WHERE iv.ID=XXXXX ON DUPLICATE KEY UPDATE ID = (SELECT MAX(ID)+1 FROM invoices) 

проблема в том, что это просто изменяет ID строки вместо копирования строки. Кто-нибудь знает, как это исправить?

// edit: Я хотел бы сделать это, не набирая все имена полей, потому что имена полей могут меняться со временем.

Обычно я использую временную таблицу. Это, вероятно, не является эффективным с точки зрения вычислительной мощности, но, похоже, работает нормально! Здесь я дублирую запись 99 в полном объеме, создавая запись 100.

 CREATE TEMPORARY TABLE tmp SELECT * FROM invoices WHERE id = 99; UPDATE tmp SET id=100 WHERE id = 99; INSERT INTO invoices SELECT * FROM tmp WHERE id = 100; 

Надеюсь, что все в порядке!

Ответ Алекса требует некоторой осторожности (например, блокировки или транзакции) в многоклиентских средах.

Предполагая, что поле AUTO ID является первым в таблице (обычный случай), мы можем использовать неявные транзакции.

     CREATE TEMPORARY TABLE tmp SELECT * из счетов-фактур ГДЕ ...;
     ALTER TABLE tmp drop ID;  # drop автоинкрементное поле
     # UPDATE tmp SET ...;  # просто нужно изменить другие уникальные ключи
     INSERT INTO invoices SELECT 0, tmp. * FROM tmp;
     DROP TABLE tmp;

Из документов MySQL:

Использование AUTO_INCREMENT: вы также можете явно назначить NULL или 0 столбцу для генерации порядковых номеров.

Вы точно знаете, что DUPLICATE KEY активируется, поэтому вы можете заранее выбрать MAX (ID) +1:

 INSERT INTO invoices SELECT MAX(ID)+1, ... other fields ... FROM invoices AS iv WHERE iv.ID=XXXXX 

Ваш подход хорош, но проблема заключается в том, что вы используете «*» вместо того, чтобы набирать имена полей. Если вы поместили все имена колонок excep primary key, ваш скрипт будет работать как очарование на одной или нескольких записях.

INSERT INTO invoices (iv.field_name, iv.field_name,iv.field_name ) SELECT iv.field_name, iv.field_name,iv.field_name FROM invoices AS iv WHERE iv.ID=XXXXX

Поздний ответ, который я знаю, но это все еще общий вопрос, я хотел бы добавить еще один ответ: «Это сработало для меня, используя только одну строчку insert into оператор, и я думаю, что это прямо, без создания новой таблицы ( поскольку это может быть проблемой с разрешениями CREATE TEMPORARY TABLE ):

 INSERT INTO invoices (col_1, col_2, col_3, ... etc) SELECT t.col_1, t.col_2, t.col_3, ... t.updated_date, FROM invoices t; 

Решение работает для столбца AUTO_INCREMENT id, в противном случае вы можете добавить столбец ID также в оператор:

 INSERT INTO invoices (ID, col_1, col_2, col_3, ... etc) SELECT MAX(ID)+1, t.col_1, t.col_2, t.col_3, ... etc , FROM invoices t; : INSERT INTO invoices (ID, col_1, col_2, col_3, ... etc) SELECT MAX(ID)+1, t.col_1, t.col_2, t.col_3, ... etc , FROM invoices t; 

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

У меня есть аналогичная проблема, и мне кажется, что я делаю

 insert into Preguntas (`EncuestaID`, `Tipo` , `Seccion` , `RespuestaID` , `Texto` ) select '23', `Tipo`, `Seccion`, `RespuestaID`, `Texto` from Preguntas where `EncuestaID`= 18 

Были Preguntas:

 CREATE TABLE IF NOT EXISTS `Preguntas` ( `ID` int(11) unsigned NOT NULL AUTO_INCREMENT, `EncuestaID` int(11) DEFAULT NULL, `Tipo` char(5) COLLATE utf8_unicode_ci DEFAULT NULL, `Seccion` int(11) DEFAULT NULL, `RespuestaID` bigint(11) DEFAULT NULL, `Texto` text COLLATE utf8_unicode_ci , PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=522 ; 

Таким образом, ID автоматически увеличивается, а также я использую фиксированное значение (’23’) для `EncuestaID

Я просто хотел продлить отличный ответ Алекса, чтобы сделать его подходящим, если вам захочется дублировать весь набор записей:

 SET @x=7; CREATE TEMPORARY TABLE tmp SELECT * FROM invoices; UPDATE tmp SET [email protected]; INSERT INTO invoices SELECT * FROM tmp; 

Я просто должен был сделать это и нашел ответ Алекса идеальным прыжком! Конечно, вы должны установить @x на самый высокий номер строки в таблице (я уверен, что вы могли бы захватить это с помощью запроса). Это полезно только в этой конкретной ситуации, поэтому будьте осторожны, если вы не хотите дублировать все строки. При необходимости отрегулируйте математику.

Мне это тоже нужно; моим решением было использовать SQLYOG (бесплатную версию) для экспорта нужной записи в виде SQL (создает вставку).

Затем я отредактировал это, чтобы удалить идентификатор, поскольку это необходимо автогенерировать, а затем скопировать вставку в SQLYog для ее выполнения. Это было безболезненно. Думаю, многие другие графические интерфейсы MySQL тоже могут это сделать.

Это дает мне запись, которую я могу использовать для тестирования в живой системе.

У меня теперь есть эта вставка для повторного использования, так как таблица переписывается ежедневно.

Небольшая вариация, основное отличие состоит в том, чтобы установить поле первичного ключа («varname») на null, что создает предупреждение, но работает. Установив первичный ключ равным нулю, автоинкремент работает при вставке записи в последний оператор.

Этот код также очищает предыдущие попытки и может запускаться более одного раза без проблем:

 DELETE FROM `tbl` WHERE varname="primary key value for new record"; DROP TABLE tmp; CREATE TEMPORARY TABLE tmp SELECT * FROM `tbl` WHERE varname="primary key value for old record"; UPDATE tmp SET varname=NULL; INSERT INTO `tbl` SELECT * FROM tmp; 
  • Медленный запрос при использовании ORDER BY
  • Ошибка Entity Framework MySQL. Указанный поставщик хранилища не может быть найден в конфигурации или недействителен
  • Java: добавьте несколько строк в MySQL с помощью PreparedStatement
  • Реализация расстояния Левенштейна для mysql / нечеткого поиска?
  • Синхронизация базы данных Mysql между двумя базами данных
  • передача LIMIT в качестве параметров для MySQL sproc
  • ВЫБЕРИТЕ * ГДЕ НЕ СУЩЕСТВУЕТ
  • Как получить возраст из поля DOB в MySQL?
  • Mysql Join Две таблицы на клавишах
  • Как избежать зарезервированных слов, используемых в качестве имен столбцов? MySQL / Создать таблицу
  • Как проводить поиск Accent Sensitive в MySql
  • Давайте будем гением компьютера.