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

时间:2012-02-06 06:26:32

标签: mysql sql insert copy

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

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

15 个答案:

答案 0 :(得分:296)

使用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

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

答案 1 :(得分:42)

IMO,最好似乎只使用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 - How to Clone an SQL Record

优点:

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

答案 2 :(得分:13)

说表格为user(id, user_name, user_email)

您可以使用此查询:

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

答案 3 :(得分:7)

对于不需要您命名列的快速,干净的解决方案,您可以使用如下所述的预准备语句: 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

免责声明:此解决方案仅适用于经常在多个表中重复复制行的人。这可能是一个流氓用户手中的危险。

答案 4 :(得分:2)

您还可以将“0”作为列的值传递给自动递增,创建记录时将使用正确的值。这比临时表简单得多。

来源: Copying rows in MySQL (参见TRiG的第二条评论,由Lore提出的第一个解决方案)

答案 5 :(得分:2)

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

答案 6 :(得分:1)

这里有很多很棒的答案。下面是为完成我正在开发的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

答案 7 :(得分:1)

如果能够使用MySQL Workbench,可以通过右键单击该行并选择“复制行”,然后右键单击该空行并选择“粘贴行”,然后更改ID来执行此操作,然后单击“应用”。

复制行:

enter image description here

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

enter image description here

更改ID:

enter image description here

应用:

enter image description here

答案 8 :(得分:0)

我一直在寻找相同的功能,但我不使用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);

答案 9 :(得分:0)

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

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

只要表中的字段相同(除了日志表上的自动增量),这样就可以正常工作。

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

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

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

注意:第二个想法,除非您正在开展一个您确定不会让其他人工作的独立项目,否则请明确列出所有字段名称并将您的日志语句更新为架构更改。这条捷径可能不值得长期头痛......尤其是在生产系统上。

答案 10 :(得分:0)

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

答案 11 :(得分:0)

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

答案 12 :(得分:0)

试试这个:

INSERT INTO test_table (SELECT null,txt FROM test_table)

每次运行此查询时,这将使用新 ID 再次插入所有行。表中的值,并且会呈指数增长。

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

答案 13 :(得分:0)

insert into your_table(col1,col2,col3) select col1+1,col2,col3 from your_table where col1=1;

注意:如果 col1 是主键,请确保在增加后 col1 的新值不是重复条目。

答案 14 :(得分:0)

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 ;