insert update语句 - 如何复制一行并在MySQL中使用自动增量字段插入同一个表中?




duplicate delete (10)

我有一个表格。 我想要做的就是复制一个自动增量列ID = 1的行,并将数据插入到行和列ID = 2的同一个表中。

使用MySql。 我如何在单个查询中执行此操作?请帮助


Answers

对于不需要命名列的快速,干净的解决方案,您可以使用准备好的语句,如下所述: https://stackoverflow.com/a/23964285/292677 : https://stackoverflow.com/a/23964285/292677

如果你需要一个复杂的解决方案,这样你可以经常这样做,你可以使用这个过程:

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

你可以运行它:

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

例子

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

免责声明:此解决方案仅适用于经常会在许多表格中反复复制行的人。 这对流氓用户来说可能是危险的。


insert into MyTable(field1, field2, id_backup)
    select field1, field2, uniqueId from MyTable where uniqueId = @Id;

您也可以传递'0'作为列自动递增的值,创建记录时将使用正确的值。 这比临时表容易得多。

来源: 在MySQL中复制行 (请参阅由TRiG提供的第二条评论,由Lore提供给第一个解决方案)


使用INSERT ... SELECT

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

其中c1, c2, ...id以外的所有列。 如果你想显式插入一个2的id ,那么将其包含在你的INSERT列表和你的SELECT中:

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

当然,你必须在第二种情况下处理可能的重复id为2的情况。


说这个表是user(id, user_name, user_email)

你可以使用这个查询:

INSERT INTO user (SELECT NULL,user_name, user_email FROM user WHERE id = 1)

将你想要的行转储到sql,然后使用生成的SQL,减去ID列导入它。


国际海事组织,最好似乎只使用sql语句来复制该行,而同时只引用您必须和想要更改的列。

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;

另请参阅av8n.com - 如何克隆SQL记录

优点:

  • SQL语句2仅提及在克隆过程中需要更改的字段。 他们不知道或关心其他领域。 其他领域只是一路顺风,保持不变。 这使得SQL语句更易于编写,更易于阅读,更容易维护并且更具可扩展性。
  • 只使用普通的MySQL语句。 不需要其他工具或编程语言。
  • 一个完全正确的记录被插入到your_table中的一个原子操作中。

我倾向于使用什么mu过短的变化张贴:

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

只要这些表具有相同的字段(除了日志表上的自动增量),那么这很好地工作。

由于我尽可能使用存储过程(为了让不熟悉数据库的其他程序员更轻松),这可以解决每次向表中添加新字段时必须返回并更新过程的问题。

它还确保了如果向表中添加新字段,它们将立即开始出现在日志表中,而无需更新数据库查询(除非您有一些显式设置字段)

警告:您需要确保同时向两个表中添加任何新字段,以便字段顺序保持不变,否则您将开始出现奇怪的错误。 如果你是唯一一个写数据库接口的人,并且你非常小心,那么这个工作很好。 否则,坚持命名你的所有领域。

注意:第二个想法是,除非您正在开发一个您确定不会有其他人正在进行工作的独立项目,否则应坚持显式列出所有字段名称,并在模式更改时更新您的日志语句。 这种快捷方式可能不值得它可能导致的长期头痛......特别是在生产系统上。


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 */

使用VALUES语法的INSERT语句可以插入多行。 为此,请包含多个列值列表,每个列表值都包含在括号内,并用逗号分隔。

例:

INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);




mysql sql insert copy