In MySQL, can I copy one row to insert into the sa

2019-01-04 16:52发布

insert into table select * from table where primarykey=1

I just want to copy one row to insert into the same table (i.e., I want to duplicate an existing row in the table) but I want to do this without having to list all the columns after the "select", because this table has too many columns.

But when I do this, I get the error:

Duplicate entry 'xxx' for key 1

I can handle this by creating another table with the same columns as a temporary container for the record I want to copy:

create table oldtable_temp like oldtable;
insert into oldtable_temp select * from oldtable where key=1;
update oldtable_tem set key=2;
insert into oldtable select * from oldtable where key=2;

Is there a simpler way to solve this?

24条回答
劳资没心,怎么记你
2楼-- · 2019-01-04 17:25

I updated @LeonardChallis's solution as it didn't work for me as none of the others. I removed the WHERE clauses and SET primaryKey = 0 in the temp table so MySQL auto-increments itself the primaryKey

CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable;
UPDATE tmptable SET primaryKey = 0;
INSERT INTO myTable SELECT * FROM tmptable;

This is of course to duplicate all the rows in the table.

查看更多
甜甜的少女心
3楼-- · 2019-01-04 17:26

If the Primary Key is Auto Increment, just specify each field except the primary key.

INSERT INTO table(field1,field2,field3) SELECT (field1,field2,field3) FROM table WHERE primarykey=1

查看更多
Melony?
4楼-- · 2019-01-04 17:29

clone row with update fields and auto increment value

CREATE TEMPORARY TABLE `temp` SELECT * FROM `testing` WHERE id = 14;

UPDATE `temp` SET id = (SELECT id FROM testing ORDER by id DESC LIMIT 1
 )+1, user_id = 252 ,policy_no = "mysffffdd12" where id = 14;

INSERT INTO `testing` SELECT * FROM `temp`;

DROP TEMPORARY TABLE IF EXISTS `temp`;
查看更多
何必那么认真
5楼-- · 2019-01-04 17:30

You almost had it with the your first query you just need to specify the columns, that way you can exclude your primary key in the insert which will enact the auto-increment you likely have on the table to automatically create a new primary key for the entry.

For example change this:

insert into table select * from table where primarykey=1

To this:

INSERT INTO table (col1, col2, col3) 
SELECT col1, col2, col3 
FROM table 
WHERE primarykey = 1

Just don't include the primarykey column in either the column list for the INSERT or for the SELECT portions of the query.

查看更多
该账号已被封号
6楼-- · 2019-01-04 17:31

Just wanted to post my piece of PHP code, because I think the way I collect the columns is a bit cleaner in code than the previous examples. Also this shows how you could easily alter an field, in this case adding a string. But you could also replace a foreign key field with the newly added record, in case you want to copy some child records as well.

  // Read columns, unset the PK (always the first field in my case)
  $stmt = $conn->prepare('SHOW COLUMNS FROM template');
  $stmt->execute();

  $columns = $stmt->fetchAll();
  $columns = array_map(function ($element) { return $element['Field']; }, $columns);

  unset($columns[0]);

  // Insert record in the database. Add string COPY to the name field.
  $sql = "INSERT INTO `template` (".implode(",", $columns).")";
  if ($key = array_search('name', $columns))
      $columns[$key] = "CONCAT(name, ' COPY')";
  $sql .= " SELECT ".implode(",", $columns)." FROM `template` WHERE `id` = ".$id;

  $stmt = $conn->prepare($sql);
  $stmt->execute();
查看更多
时光不老,我们不散
7楼-- · 2019-01-04 17:33

max233 was certainly on the right track, at least for the autoincrement case. However, do not do the ALTER TABLE. Simply set the auto-increment field in the temporary table to NULL. This will present an error, but the following INSERT of all fields in the temporary table will happen and the the NULL auto field will obtain a unique value.

查看更多
登录 后发表回答