如何复制一行和插入在同一个表与自增字段在MySQL?

在MySQL中,我试图复制一行与自动增量 column ID=1插入数据到同一个表作为一个新行与column ID=2

如何在单个查询中做到这一点?

608347 次浏览

使用INSERT ... SELECT:

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

其中c1, c2, ...是除id之外的所有列。如果你想显式地插入id为2,那么在你的insert列列表和SELECT中包含它:

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

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

假设表是user(id, user_name, user_email)

你可以使用这个查询:

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

在我看来,最好的方法似乎是只使用sql语句复制该行,同时只引用必须和想要更改的列。

CREATE TEMPORARY TABLE temp_table ENGINE=MEMORY


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


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

另见如何克隆一个SQL记录

好处:

  • SQL语句2只提到在克隆过程中需要更改的字段。他们不了解或不关心其他领域。其他字段只是随大流,没有变化。这使得SQL语句更易于编写、阅读、维护和扩展。
  • 只使用普通的MySQL语句。不需要其他工具或编程语言。
  • 一个完全正确的记录在一个原子操作中插入到your_table中。

我正在寻找相同的功能,但我不使用MySQL。我想复制所有的字段,当然除了主键(id)。这是一次性查询,不能在任何脚本或代码中使用。

我找到了PL/SQL的方法,但我相信任何其他SQL IDE都可以做到。我做了一个基本的

SELECT *
FROM mytable
WHERE id=42;

然后将其导出到一个SQL文件,在那里我可以找到

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

我只是编辑并使用它:

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

您还可以传入'0'作为列的值来自动递增,在创建记录时将使用正确的值。这比临时表简单多了。

< p >来源: 在MySQL中复制行 (见TRiG对第一个解的第二个注释,Lore)

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

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

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;

这有助于,它支持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;

我倾向于使用mu太短的变体:

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

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

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

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

警告:你要确保在同一时间向两个表中添加任何新字段,以便字段顺序保持相同…否则你就会开始出现奇怪的bug。如果你是唯一一个编写数据库接口的人,并且你非常小心,那么这工作得很好。否则,请坚持为所有字段命名。

注意:转念一想,除非你在做一个单独的项目,你确定不会有其他人在做,否则坚持显式列出所有字段名,并在模式更改时更新日志语句。这条捷径可能不值得它带来的长期头痛……特别是在生产系统上。

转储您想要sql的行,然后使用生成的sql,减去ID列,将其导入。

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

这里有很多很棒的答案。下面是我为正在开发的Web应用程序编写的存储过程示例:

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON


-- Create Temporary Table
SELECT * INTO #tempTable FROM <YourTable> WHERE Id = Id


--To trigger the auto increment
UPDATE #tempTable SET Id = NULL


--Update new data row in #tempTable here!


--Insert duplicate row with modified data back into your table
INSERT INTO <YourTable> SELECT * FROM #tempTable


-- Drop Temporary Table
DROP TABLE #tempTable

如果你能使用MySQL Workbench,你可以通过右键单击行并选择“复制行”,然后右键单击空行并选择“粘贴行”,然后更改ID,然后单击“应用”来做到这一点。

复制行:

enter image description here

将复制的行粘贴到空白行:

enter image description here

更改ID:

enter image description here

应用:

enter image description here

试试这个:

INSERT INTO test_table (SELECT null,txt FROM test_table)

每次运行此查询时,这将再次插入所有具有新id的行。值将呈指数增长。

我使用了一个有两列的表,即id和txt, id是自动递增的。

Insert into your table(col1,col2,col3) select col1+1,col2,col3 from your_table where col1=1;

注意:如果col1是主键,请确保自增后col1的新值不是重复项。

CREATE TEMPORARY  TABLE IF NOT EXISTS  `temp_table` LIKE source_table;
DELETE FROM `purchasing2` ;
INSERT INTO temp_table SELECT * FROM source_table where columnid = 2;
ALTER TABLE temp_table MODIFY id INT NOT NULL;
ALTER TABLE temp_table DROP PRIMARY KEY;
UPDATE temp_table SET id=NULL ;
INSERT INTO source_table SELECT * FROM temp_table;
DROP TEMPORARY  TABLE IF EXISTS  temp_table ;