¿Cómo copiar una fila e insertar en la misma tabla con un campo autoincrement en MySQL?


Tengo una tabla Eg - tab . Lo que estoy tratando de hacer es copiar una fila con una columna de autoincremento ID=1 e insertar los datos en la misma tabla con una fila y columna ID=2.

Usando MySQL. ¿Cómo puedo hacer esto en una sola consulta?Por favor ayuda

Author: mu is too short, 2012-02-06

11 answers

Use INSERT ... SELECT:

insert into your_table (c1, c2, ...)
select c1, c2, ...
from your_table
where id = 1

Donde c1, c2, ... están todas las columnas excepto id. Si desea insertar explícitamente con un id de 2, inclúyalo en su lista de columnas de INSERCIÓN y SELECCIONE:

insert into your_table (id, c1, c2, ...)
select 2, c1, c2, ...
from your_table
where id = 1

Tendrás Que cuidar de un posible duplicado id 2 en el segundo caso, por supuesto.

 270
Author: mu is too short,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-06 06:31:27

IMO, lo mejor parece usar instrucciones sql solo para copiar esa fila, mientras que al mismo tiempo solo hace referencia a las columnas que debe y desea cambiar.

CREATE TEMPORARY TABLE temp_table ENGINE=MEMORY

SELECT * FROM your_table WHERE id=1;
UPDATE temp_table SET id=NULL; /* Update other values at will. */

INSERT INTO your_table SELECT * FROM temp_table;
DROP TABLE temp_table;

Véase también av8n.com -Cómo clonar un registro SQL

Beneficios:

  • Las instrucciones SQL 2 solo mencionan los campos que deben cambiarse durante el proceso de clonación. No conocen ni se preocupan por otros campos. Los otros campos solo van a lo largo del viaje, sin cambios. Esto hace que el SQL declaraciones más fáciles de escribir, más fáciles de leer, más fáciles de mantener y más extensibles.
  • Solo se utilizan sentencias MySQL ordinarias. No se requieren otras herramientas o lenguajes de programación.
  • Un registro completamente correcto se inserta en your_table en una operación atómica.
 36
Author: parvus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-12 06:53:33

Digamos que la tabla es user(id, user_name, user_email).

Puede utilizar esta consulta:

INSERT INTO user (SELECT NULL,user_name, user_email FROM user WHERE id = 1)
 13
Author: Vijay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-06 06:35:39

Para una solución rápida y limpia que no requiera nombrar columnas, puede usar una instrucción preparada como se describe aquí: https://stackoverflow.com/a/23964285/292677

Si necesita una solución compleja para que pueda hacer esto con frecuencia, puede usar este procedimiento:

DELIMITER $$

CREATE PROCEDURE `duplicateRows`(_schemaName text, _tableName text, _whereClause text, _omitColumns text)
SQL SECURITY INVOKER
BEGIN
  SELECT IF(TRIM(_omitColumns) <> '', CONCAT('id', ',', TRIM(_omitColumns)), 'id') INTO @omitColumns;

  SELECT GROUP_CONCAT(COLUMN_NAME) FROM information_schema.columns 
  WHERE table_schema = _schemaName AND table_name = _tableName AND FIND_IN_SET(COLUMN_NAME,@omitColumns) = 0 ORDER BY ORDINAL_POSITION INTO @columns;

  SET @sql = CONCAT('INSERT INTO ', _tableName, '(', @columns, ')',
  'SELECT ', @columns, 
  ' FROM ', _schemaName, '.', _tableName, ' ',  _whereClause);

  PREPARE stmt1 FROM @sql;
  EXECUTE stmt1;
END

Puedes ejecutarlo con:

CALL duplicateRows('database', 'table', 'WHERE condition = optional', 'omit_columns_optional');

Ejemplos

duplicateRows('acl', 'users', 'WHERE id = 200'); -- will duplicate the row for the user with id 200
duplicateRows('acl', 'users', 'WHERE id = 200', 'created_ts'); -- same as above but will not copy the created_ts column value    
duplicateRows('acl', 'users', 'WHERE id = 200', 'created_ts,updated_ts'); -- same as above but also omits the updated_ts column
duplicateRows('acl', 'users'); -- will duplicate all records in the table

DESCARGO DE RESPONSABILIDAD: Esta solución es solo para alguien que duplicará repetidamente filas en muchas tablas, a menudo. Podría ser peligroso en las manos de un usuario deshonesto.

 6
Author: curmil,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:03:06

Esto ayudó y soporta columnas BLOB/TEXT.

CREATE TEMPORARY TABLE temp_table
AS
SELECT * FROM source_table WHERE id=2;
UPDATE temp_table SET id=NULL WHERE id=2;
INSERT INTO source_table SELECT * FROM temp_table;
DROP TEMPORARY TABLE temp_table;
USE source_table;
 5
Author: Petr Hladík,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-14 04:16:24

También puede pasar '0' como el valor para que la columna se incremente automáticamente, el valor correcto se usará cuando se cree el registro. Esto es mucho más fácil que las mesas temporales.

Fuente: Copiando filas en MySQL (ver el segundo comentario, por trigonometría, a la primera solución, por tradición)

 2
Author: Mark Pruce,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:50
insert into MyTable(field1, field2, id_backup)
    select field1, field2, uniqueId from MyTable where uniqueId = @Id;
 2
Author: IR.Programmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-15 19:11:18

Estaba buscando la misma característica, pero no uso MySQL. Quería copiar TODOS los campos excepto, por supuesto, la clave primaria (id). Esta fue una consulta de un solo disparo, no se debe usar en ningún script o código.

Encontré mi camino alrededor con PL / SQL, pero estoy seguro de que cualquier otro IDE SQL haría. Hice un {[4 básico]}

SELECT * 
FROM mytable 
WHERE id=42;

Luego exportarlo a un archivo SQL donde pude encontrar el

INSERT INTO table (col1, col2, col3, ... , col42) 
VALUES (1, 2, 3, ..., 42);

Acabo de editarlo y lo usé :

INSERT INTO table (col1, col2, col3, ... , col42) 
VALUES (mysequence.nextval, 2, 3, ..., 42);
 0
Author: SabineA,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-03 16:16:27

Tiendo a usar una variación de lo que mu es demasiado corto publicado:

INSERT INTO something_log
SELECT NULL, s.*
FROM something AS s
WHERE s.id = 1;

Mientras las tablas tengan campos idénticos (excepto el incremento automático en la tabla de registro), entonces esto funciona muy bien.

Dado que uso procedimientos almacenados siempre que es posible (para facilitar la vida a otros programadores que no están muy familiarizados con las bases de datos), esto resuelve el problema de tener que volver y actualizar procedimientos cada vez que agrega un nuevo campo a una tabla.

También se asegura de que si agrega nuevo los campos a una tabla comenzarán a aparecer en la tabla de registro inmediatamente sin tener que actualizar sus consultas de base de datos (a menos que, por supuesto, tenga algunos que establezcan un campo explícitamente)

Advertencia: Querrá asegurarse de agregar cualquier campo nuevo a ambas tablas al mismo tiempo para que el orden de los campos permanezca igual... de lo contrario, comenzará a recibir errores extraños. Si usted es el único que escribe interfaces de base de datos Y es muy cuidadoso, entonces esto funciona muy bien. De lo contrario, apégate a nombrar todos tus campos.

Nota: Pensándolo bien, a menos que esté trabajando en un proyecto en solitario que esté seguro de que no habrá otros trabajando en él, siga enumerando todos los nombres de campo explícitamente y actualice sus instrucciones de registro a medida que cambie su esquema. Este atajo probablemente no vale la pena el dolor de cabeza a largo plazo que puede causar... especialmente en un sistema de producción.

 0
Author: Privateer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-09 16:29:10

Volcar la fila que desea sql y luego utilizar el SQL generado, menos la columna ID para importarlo de nuevo.

 0
Author: Claire,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-15 11:01:11
INSERT INTO `dbMyDataBase`.`tblMyTable` 
(
    `IdAutoincrement`, 
    `Column2`, 
    `Column3`, 
    `Column4` 
) 

SELECT 
    NULL,  
    `Column2`, 
    `Column3`, 
    'CustomValue' AS Column4 
FROM `dbMyDataBase`.`tblMyTable` 
WHERE `tblMyTable`.`Column2` = 'UniqueValueOfTheKey' 
; 
/* mySQL 5.6 */
 0
Author: Wojciech Skibiński,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-02 01:36:46