在MySQL中,我可以复制一行插入同一张表中吗?

发布于 2024-09-29 20:57:41 字数 527 浏览 1 评论 0原文

insert into table select * from table where primarykey=1

我只想复制一行以插入到同一个表中(即,我想复制表中的现有行),但我想这样做而不必列出“select”之后的所有列,因为该表有太多的列。

但是当我这样做时,我收到错误:

密钥 1 的条目“xxx”重复

我可以通过创建另一个表来处理此问题,该表具有相同的列作为我要复制的记录的临时容器:

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;

是否有更简单的方法来解决此问题?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(27

扬花落满肩 2024-10-06 20:57:44
$slugform = 'yourslugmarkthisrow';
$userrid = Auth::id();
$newformslug = Str::random(30);
$rndkata = 'ztemp_' . $userrid . '_' . strtolower(Str::random(10));

//single row duplicate , for main table
$query  = "CREATE TEMPORARY TABLE {$rndkata} SELECT * FROM ap_forms WHERE form_slug = ?;";
$kimona1 = DB::statement($query, [$slugform]);
$query  = "UPDATE {$rndkata} SET form_slug = ?, user_id = ?, form_id = NULL;";
$kimona1 = DB::statement($query, [$newformslug, $userrid]);
$query  = "INSERT INTO ap_forms SELECT * FROM {$rndkata}  LIMIT 1;";
$kimona1 = DB::statement($query);
$query  = "DROP TEMPORARY TABLE IF EXISTS {$rndkata};";
$kimona1 = DB::statement($query);

$newform_id = app('db')->query()->selectRaw(' form_id as oke from ap_forms where form_slug = ?', [$newformslug])->value('oke');

Log::info($newform_id);
$rndkata2 = 'element_' . $rndkata;

//multiple rows duplicate with new form_id and id autoincrement
$query  = "CREATE TEMPORARY TABLE {$rndkata2} SELECT * FROM ap_form_elements WHERE form_id = ?;";
$kimona1 = DB::statement($query, [$form_id]);
$query  = "UPDATE {$rndkata2} SET form_id = ?, id = NULL;";
$kimona1 = DB::statement($query, [$newform_id]);
$query  = "INSERT INTO ap_form_elements SELECT * FROM {$rndkata2};";
$kimona1 = DB::statement($query);
$query  = "DROP TEMPORARY TABLE IF EXISTS {$rndkata2};";
$kimona1 = DB::statement($query);
$slugform = 'yourslugmarkthisrow';
$userrid = Auth::id();
$newformslug = Str::random(30);
$rndkata = 'ztemp_' . $userrid . '_' . strtolower(Str::random(10));

//single row duplicate , for main table
$query  = "CREATE TEMPORARY TABLE {$rndkata} SELECT * FROM ap_forms WHERE form_slug = ?;";
$kimona1 = DB::statement($query, [$slugform]);
$query  = "UPDATE {$rndkata} SET form_slug = ?, user_id = ?, form_id = NULL;";
$kimona1 = DB::statement($query, [$newformslug, $userrid]);
$query  = "INSERT INTO ap_forms SELECT * FROM {$rndkata}  LIMIT 1;";
$kimona1 = DB::statement($query);
$query  = "DROP TEMPORARY TABLE IF EXISTS {$rndkata};";
$kimona1 = DB::statement($query);

$newform_id = app('db')->query()->selectRaw(' form_id as oke from ap_forms where form_slug = ?', [$newformslug])->value('oke');

Log::info($newform_id);
$rndkata2 = 'element_' . $rndkata;

//multiple rows duplicate with new form_id and id autoincrement
$query  = "CREATE TEMPORARY TABLE {$rndkata2} SELECT * FROM ap_form_elements WHERE form_id = ?;";
$kimona1 = DB::statement($query, [$form_id]);
$query  = "UPDATE {$rndkata2} SET form_id = ?, id = NULL;";
$kimona1 = DB::statement($query, [$newform_id]);
$query  = "INSERT INTO ap_form_elements SELECT * FROM {$rndkata2};";
$kimona1 = DB::statement($query);
$query  = "DROP TEMPORARY TABLE IF EXISTS {$rndkata2};";
$kimona1 = DB::statement($query);
混浊又暗下来 2024-10-06 20:57:44

这就是我在谷歌上发现的,因为我发现这很有帮助但有问题,所以我想为其他挖掘这个问题的人做出重要的修改。

首先,我使用的是 SQL Server,而不是 MySQL,但我认为它应该类似地工作。我使用了 Leonard Challis 的解决方案,因为它最简单并且满足了需求,但是这有一个问题 - 如果您只是简单地获取 PK 并将其增加 1,那么如果您在添加相关行后添加了其他记录,会发生什么情况。我决定最好让系统处理 PK 的自动增量,因此我执行了以下操作:

SELECT * INTO #tmpTable FROM Table WHERE primarykey = 1
--Optionally you can modify one or more fields here like this: 
--UPDATE #tmpTable SET somefield = newData
ALTER TABLE #tmpTable DROP COLUMN TicketUpdateID
INSERT INTO Tickets SELECT * FROM #tmpTable
DROP TABLE #tmpTable

我相信这在 MySQL 中也能类似地工作,但我没有对此进行测试。

This is what I turned up with google and since I found this helpful but problematic I wanted to contribute an important modification for anyone else who digs this up.

First off, I'm using SQL Server, not MySQL, but I think it should work similarly. I used Leonard Challis' solution because it was simplest and met the need, however there's a problem with this - if you simply take the PK and increment it by 1 then what happens if you've added other records since the row in question was added. I decided it was best to just let the system handle the autoincrementing of the PK, so I did the following:

SELECT * INTO #tmpTable FROM Table WHERE primarykey = 1
--Optionally you can modify one or more fields here like this: 
--UPDATE #tmpTable SET somefield = newData
ALTER TABLE #tmpTable DROP COLUMN TicketUpdateID
INSERT INTO Tickets SELECT * FROM #tmpTable
DROP TABLE #tmpTable

I believe this would work similarly in MySQL, but I didn't test this.

萌︼了一个春 2024-10-06 20:57:43

我会在下面使用,

insert into ORDER_ITEM select * from ORDER_ITEM where ITEM_NUMBER =123;

I would use below,

insert into ORDER_ITEM select * from ORDER_ITEM where ITEM_NUMBER =123;
美男兮 2024-10-06 20:57:43

我只需要这样做,这是我的手动解决方案:

  1. phpmyadmin中,选中您要复制的行在
  2. 查询结果操作下的底部单击“导出”
  3. 下一页选中“另存为文件”,然后单击“执行”
  4. 使用文本编辑器打开导出的文件,找到主字段的值并将其更改为唯一的值。
  5. 返回phpmyadmin,单击'导入'选项卡,在浏览下找到要导入.sql文件的文件,单击'Go' 并且应该插入重复的行。

如果您不知道 PRIMARY 字段是什么,请返回您的 phpmyadmin 页面,单击'Structure' 选项卡,然后单击在页面底部的'索引'下,它将显示哪个'字段'具有'Keyname''PRIMARY'< /强>。

有点绕,但如果您不想处理标记而只需要复制一行,那么您就可以了。

I just had to do this and this was my manual solution:

  1. In phpmyadmin, check the row you wish to copy
  2. At the bottom under query result operations click 'Export'
  3. On the next page check 'Save as file' then click 'Go'
  4. Open the exported file with a text editor, find the value of the primary field and change it to something unique.
  5. Back in phpmyadmin click on the 'Import' tab, locate the file to import .sql file under browse, click 'Go' and the duplicate row should be inserted.

If you don't know what the PRIMARY field is, look back at your phpmyadmin page, click on the 'Structure' tab and at the bottom of the page under 'Indexes' it will show you which 'Field' has a 'Keyname' value 'PRIMARY'.

Kind of a long way around, but if you don't want to deal with markup and just need to duplicate a single row there you go.

成熟的代价 2024-10-06 20:57:43

只是想发布我的一段 PHP 代码,因为我认为我收集列的方式在代码中比前面的示例更干净一些。此外,这还展示了如何轻松更改字段,在本例中添加字符串。但是,如果您还想复制一些子记录,您也可以用新添加的记录替换外键字段。

  // 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();

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();
儭儭莪哋寶赑 2024-10-06 20:57:43

上面显示的这个解决方案也适用于选定的行。例如,我正在为我的 Nice2work 项目创建演示行,这非常完美。

CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable WHERE id=500;
UPDATE tmptable SET id = 0;
UPDATE some fields I need to change
INSERT INTO myTable SELECT * FROM tmptable;
DROP TABLE tmptable;

//  You can use this same also directly into your code like (PHP Style)
$sql = "CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable WHERE id=500;
UPDATE tmptable SET id = 0;
UPDATE some fields I need to change
INSERT INTO myTable SELECT * FROM tmptable;DROP TABLE tmptable;";

This solution showed above works perfect also for selected rows. For example I am creating demonstration rows for my nice2work project, and this works perfect.

CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable WHERE id=500;
UPDATE tmptable SET id = 0;
UPDATE some fields I need to change
INSERT INTO myTable SELECT * FROM tmptable;
DROP TABLE tmptable;

//  You can use this same also directly into your code like (PHP Style)
$sql = "CREATE TEMPORARY TABLE tmptable SELECT * FROM myTable WHERE id=500;
UPDATE tmptable SET id = 0;
UPDATE some fields I need to change
INSERT INTO myTable SELECT * FROM tmptable;DROP TABLE tmptable;";
攀登最高峰 2024-10-06 20:57:43

我知道这是一个老问题,但这里有另一个解决方案:

假设主键是自动递增的,这会复制主表中的一行,并使用新的主表 ID 创建链接表数据的副本。

获取列名称的其他选项:
-显示表名中的列; (列名称:字段)
-DESCRIBE 表名(列名:字段)
-SELECT column_name FROM information_schema.columns WHERE table_name = 'tablename' (列名称:column_name)

//First, copy main_table row
$ColumnHdr='';
$Query="SHOW COLUMNS FROM `main_table`;";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
while($Row=mysql_fetch_array($Result))
{
    if($Row['Field']=='MainTableID')     //skip main table id in column list
        continue;
    $ColumnHdr.=",`" . $Row['Field'] . "`";
}
$Query="INSERT INTO `main_table` (" . substr($ColumnHdr,1) . ")
        (SELECT " . substr($ColumnHdr,1) . " FROM `main_table`
            WHERE `MainTableID`=" . $OldMainTableID . ");";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
$NewMainTableID=mysql_insert_id($link);

//Change the name (assumes a 30 char field)
$Query="UPDATE `main_table` SET `Title`=CONCAT(SUBSTRING(`Title`,1,25),' Copy') WHERE `MainTableID`=" . $NewMainTableID . ";";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);

//now copy in the linked tables
$TableArr=array("main_table_link1","main_table_link2","main_table_link3");
foreach($TableArr as $TableArrK=>$TableArrV)
{
    $ColumnHdr='';
    $Query="SHOW COLUMNS FROM `" . $TableArrV . "`;";
    $Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
    while($Row=mysql_fetch_array($Result))
    {
        if($Row['Field']=='MainTableID')     //skip main table id in column list, re-added in query
            continue;
        if($Row['Field']=='dbID')    //skip auto-increment,primary key in linked table
            continue;
        $ColumnHdr.=",`" . $Row['Field'] . "`";
    }

    $Query="INSERT INTO `" . $TableArrV . "` (`MainTableID`," . substr($ColumnHdr,1) . ")
            (SELECT " . $NewMainTableID . "," . substr($ColumnHdr,1) . " FROM `" . $TableArrV . "`
             WHERE `MainTableID`=" . $OldMainTableID . ");";
    $Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
}

I know it's an old question, but here is another solution:

This duplicates a row in the main table, assuming the primary key is auto-increment, and creates copies of linked-tables data with the new main table id.

Other options for getting column names:
-SHOW COLUMNS FROM tablename; (Column name: Field)
-DESCRIBE tablename (Column name: Field)
-SELECT column_name FROM information_schema.columns WHERE table_name = 'tablename' (Column name: column_name)

//First, copy main_table row
$ColumnHdr='';
$Query="SHOW COLUMNS FROM `main_table`;";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
while($Row=mysql_fetch_array($Result))
{
    if($Row['Field']=='MainTableID')     //skip main table id in column list
        continue;
    $ColumnHdr.=",`" . $Row['Field'] . "`";
}
$Query="INSERT INTO `main_table` (" . substr($ColumnHdr,1) . ")
        (SELECT " . substr($ColumnHdr,1) . " FROM `main_table`
            WHERE `MainTableID`=" . $OldMainTableID . ");";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
$NewMainTableID=mysql_insert_id($link);

//Change the name (assumes a 30 char field)
$Query="UPDATE `main_table` SET `Title`=CONCAT(SUBSTRING(`Title`,1,25),' Copy') WHERE `MainTableID`=" . $NewMainTableID . ";";
$Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);

//now copy in the linked tables
$TableArr=array("main_table_link1","main_table_link2","main_table_link3");
foreach($TableArr as $TableArrK=>$TableArrV)
{
    $ColumnHdr='';
    $Query="SHOW COLUMNS FROM `" . $TableArrV . "`;";
    $Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
    while($Row=mysql_fetch_array($Result))
    {
        if($Row['Field']=='MainTableID')     //skip main table id in column list, re-added in query
            continue;
        if($Row['Field']=='dbID')    //skip auto-increment,primary key in linked table
            continue;
        $ColumnHdr.=",`" . $Row['Field'] . "`";
    }

    $Query="INSERT INTO `" . $TableArrV . "` (`MainTableID`," . substr($ColumnHdr,1) . ")
            (SELECT " . $NewMainTableID . "," . substr($ColumnHdr,1) . " FROM `" . $TableArrV . "`
             WHERE `MainTableID`=" . $OldMainTableID . ");";
    $Result=Wrappedmysql_query($Query,$link,__FILE__,__LINE__);
}
潦草背影 2024-10-06 20:57:43

创建一个表

    CREATE TABLE `sample_table` (
       `sample_id` INT(10) unsigned NOT NULL AUTO_INCREMENT,
       `sample_name` VARCHAR(255) NOT NULL,
       `sample_col_1` TINYINT(1) NOT NULL,
       `sample_col_2` TINYINT(2) NOT NULL,

      PRIMARY KEY (`sample_id`),
      UNIQUE KEY `sample_id` (`sample_id`)

    ) ENGINE='InnoDB' DEFAULT CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';

插入一行

INSERT INTO `sample_table`
   VALUES(NULL, 'sample name', 1, 2);

克隆行插入上面

INSERT INTO `sample_table`
   SELECT 
    NULL AS `sample_id`, -- new AUTO_INCREMENT PRIMARY KEY from MySQL
    'new dummy entry' AS `sample_name`,  -- new UNIQUE KEY from you
    `sample_col_1`, -- col from old row
    `sample_col_2` -- col from old row
   FROM `sample_table`
   WHERE `sample_id` = 1;

测试

SELECT * FROM `sample_table`;

Create a table

    CREATE TABLE `sample_table` (
       `sample_id` INT(10) unsigned NOT NULL AUTO_INCREMENT,
       `sample_name` VARCHAR(255) NOT NULL,
       `sample_col_1` TINYINT(1) NOT NULL,
       `sample_col_2` TINYINT(2) NOT NULL,

      PRIMARY KEY (`sample_id`),
      UNIQUE KEY `sample_id` (`sample_id`)

    ) ENGINE='InnoDB' DEFAULT CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';

Insert a row

INSERT INTO `sample_table`
   VALUES(NULL, 'sample name', 1, 2);

Clone row insert above

INSERT INTO `sample_table`
   SELECT 
    NULL AS `sample_id`, -- new AUTO_INCREMENT PRIMARY KEY from MySQL
    'new dummy entry' AS `sample_name`,  -- new UNIQUE KEY from you
    `sample_col_1`, -- col from old row
    `sample_col_2` -- col from old row
   FROM `sample_table`
   WHERE `sample_id` = 1;

Test

SELECT * FROM `sample_table`;
木森分化 2024-10-06 20:57:43

这是我在这个网站上在线找到的答案
描述如何执行上述操作1
您可以在页面底部找到答案。基本上,您所做的是将要复制的行复制到内存中保存的临时表中。然后,您可以使用 update 更改主键编号。然后将其重新插入到目标表中。然后你放下桌子。

这是它的代码:

创建临时表rescueteam ENGINE=MEMORY SELECT * FROMfitnessreport4 WHERE rID=1;# 1 行受影响。
UPDATE rescueteam SET rID=Null WHERE rID=1;# 1 行受影响。INSERT
INTO fitnessreport4 SELECT * FROM rescueteam;# 1 行受影响。
DROP TABLE rescueteam# MySQL 返回一个空结果集(即零
行)。

我创建了临时表rescueteam。我从原始表 Fitnessreport4 中复制了该行。然后,我将临时表中的行的主键设置为 null,以便我可以将其复制回原始表,而不会出现重复键错误。我昨天晚上尝试了这段代码并且有效。

Here's an answer I found online at this site
Describes how to do the above1
You can find the answer at the bottom of the page. Basically, what you do is copy the row to be copied to a temporary table held in memory. You then change the Primary Key number using update. You then re-insert it into the target table. You then drop the table.

This is the code for it:

CREATE TEMPORARY TABLE rescueteam ENGINE=MEMORY SELECT * FROMfitnessreport4 WHERE rID=1;# 1 row affected.
UPDATE rescueteam SET rID=Null WHERE rID=1;# 1 row affected.INSERT
INTO fitnessreport4 SELECT * FROM rescueteam;# 1 row affected.
DROP TABLE rescueteam# MySQL returned an empty result set (i.e. zero
rows).

I created the temporary table rescueteam. I copied the row from my original table fitnessreport4. I then set the primary key for the row in the temporary table to null so that I can copy it back to the original table without getting a Duplicate Key error. I tried this code yesterday evening and it worked.

北陌 2024-10-06 20:57:43

这是对“Grim...”答案的附加解决方案
有一些关于主键为空的评论。
关于它的一些评论不起作用。
以及对解决方案的一些评论。
这些解决方案都不适合我们。我们有带有 InnoDB 表的 MariaDB。

我们无法将主键设置为允许为空。
使用 0 而不是 NULL 会导致主键出现重复值错误。
SET SQL_SAFE_UPDATES = 0; 也不起作用。

如果我们将主键更改为唯一,那么“严峻...”的解决方案确实有效

This is an additional solution to the answer by "Grim..."
There have been some comments on it having a primary key as null.
Some comments about it not working.
And some comments on solutions.
None of the solutions worked for us. We have MariaDB with the InnoDB table.

We could not set the primary key to allow null.
Using 0 instead of NULL led to duplicate value error for the primary key.
SET SQL_SAFE_UPDATES = 0; Did not work either.

The solution from "Grim..." did work IF we changed our PRIMARY KEY to UNIQUE instead

西瑶 2024-10-06 20:57:43

max233 肯定是在正确的轨道上,至少对于自动增量的情况来说是这样。
但是,不要执行 ALTER TABLE。只需在其中设置自动增量字段即可
临时表为NULL。这将出现错误,但以下 INSERT
临时表中的所有字段都会发生并且NULL auto字段将获得
独特的价值。

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 NULL auto field will obtain
a unique value.

朦胧时间 2024-10-06 20:57:43

根据上面的答案以及 SO 上其他地方的答案,我将其作为克隆一条记录的最终代码:

CREATE TEMPORARY TABLE temptable SELECT * FROM things WHERE Thing_ID = 10000345;
UPDATE temptable SET Thing_ID = 0;
INSERT INTO things SELECT * FROM temptable;
DROP TEMPORARY TABLE IF EXISTS temptable;

将主键 Thing_ID 的值设置为 = 0 比更改临时表以允许 NULL 然后设置要短PRIMARY key 为 NULL - 对我来说,它在 MySQL 中有效。

Drawing from answers above, and elsewhere on SO, I came to this as my final code for cloning one record:

CREATE TEMPORARY TABLE temptable SELECT * FROM things WHERE Thing_ID = 10000345;
UPDATE temptable SET Thing_ID = 0;
INSERT INTO things SELECT * FROM temptable;
DROP TEMPORARY TABLE IF EXISTS temptable;

Setting the value of the PRIMARY key, the Thing_ID, to be = 0 is shorter than altering the temptable to allow NULL and then setting the PRIMARY key to NULL - and, for me, it works in MySQL.

找回味觉 2024-10-06 20:57:42

如果表的主键字段是自增字段,则可以使用列查询。例如,名为 test_tbl 的表有 3 个字段:id、name、ageid 是主键字段并且自动递增,因此您可以使用以下查询来复制行:

INSERT INTO `test_tbl` (`name`,`age`) SELECT `name`,`age` FROM `test_tbl`;

此查询会导致复制每一行。


如果您的表的主键字段不是自动递增字段,则可以使用以下方法:

INSERT INTO `test_tbl` (`id`,`name`,`age`)
  SELECT 20,`name`,`age` FROM `test_tbl` WHERE id = 19;

此查询的结果是插入 id=20< 的重复行 id=19 /代码>。

If your table's primary key field is an auto increment field, then you can use query with columns. For example, your table named test_tbl has 3 fields as id, name, age. id is a primary key field and auto increment, so you can use the following query to duplicate the row:

INSERT INTO `test_tbl` (`name`,`age`) SELECT `name`,`age` FROM `test_tbl`;

This query results in duplicating every row.


If your table's primary key field is not an auto increment field, then you can use the following method:

INSERT INTO `test_tbl` (`id`,`name`,`age`)
  SELECT 20,`name`,`age` FROM `test_tbl` WHERE id = 19;

The result of this query is a duplicate row of id=19 inserted as id=20.

私野 2024-10-06 20:57:42

我使用了 Grim 的技术,做了一点改变:如果有人寻找这个查询是因为由于主键问题而无法执行简单的查询:

INSERT INTO table SELECT * FROM table WHERE primakey=1;

随着我的 MySql 安装 5.6.26,键不可为空并产生错误:

#1048 - Column 'primakey' cannot be null 

所以之后创建临时表我将主键更改为可为空。

CREATE TEMPORARY TABLE tmptable_1 SELECT * FROM table WHERE primarykey = 1;
ALTER TABLE tmptable_1 MODIFY primarykey int(12) null;
UPDATE tmptable_1 SET primarykey = NULL;
INSERT INTO table SELECT * FROM tmptable_1;
DROP TEMPORARY TABLE IF EXISTS tmptable_1;

I used Grim's technique with a little change: If someone looking for this query is because can't do a simple query due to primary key problem:

INSERT INTO table SELECT * FROM table WHERE primakey=1;

With my MySql install 5.6.26, key isn't nullable and produce an error:

#1048 - Column 'primakey' cannot be null 

So after create temporary table I change the primary key to a be nullable.

CREATE TEMPORARY TABLE tmptable_1 SELECT * FROM table WHERE primarykey = 1;
ALTER TABLE tmptable_1 MODIFY primarykey int(12) null;
UPDATE tmptable_1 SET primarykey = NULL;
INSERT INTO table SELECT * FROM tmptable_1;
DROP TEMPORARY TABLE IF EXISTS tmptable_1;
强辩 2024-10-06 20:57:42

克隆具有更新字段和自动增量值的行

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 = "mysdddd12" where id = 14;

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

DROP TEMPORARY TABLE IF EXISTS `temp`;

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 = "mysdddd12" where id = 14;

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

DROP TEMPORARY TABLE IF EXISTS `temp`;
離人涙 2024-10-06 20:57:42

我在 Koha 数据库 中使用在条形码 列中插入带有“C”前缀的重复项目:

INSERT INTO items (`biblionumber`, `biblioitemnumber`, `barcode`, `dateaccessioned` ) SELECT `biblionumber`, `biblioitemnumber`,  CONCAT('C',`barcode`), `dateaccessioned` FROM `items` WHERE barcode='14832';

I used in my Koha database to insert duplicate items with the 'C' prefix in barcode column:

INSERT INTO items (`biblionumber`, `biblioitemnumber`, `barcode`, `dateaccessioned` ) SELECT `biblionumber`, `biblioitemnumber`,  CONCAT('C',`barcode`), `dateaccessioned` FROM `items` WHERE barcode='14832';
蒲公英的约定 2024-10-06 20:57:42

以下一些内容是从该网站收集的。这就是我在具有任意数量字段的表中复制记录的方法:

这还假设您在表的开头有一个 AI 字段

function duplicateRow( $id = 1 ){
dbLink();//my db connection
$qColumnNames = mysql_query("SHOW COLUMNS FROM table") or die("mysql error");
$numColumns = mysql_num_rows($qColumnNames);

for ($x = 0;$x < $numColumns;$x++){
$colname[] = mysql_fetch_row($qColumnNames);
}

$sql = "SELECT * FROM table WHERE tableId = '$id'";
$row = mysql_fetch_row(mysql_query($sql));
$sql = "INSERT INTO table SET ";
for($i=1;$i<count($colname)-4;$i++){//i set to 1 to preclude the id field
//we set count($colname)-4 to avoid the last 4 fields (good for our implementation)
$sql .= "`".$colname[$i][0]."`  =  '".$row[$i]. "', ";
}
$sql .= " CreateTime = NOW()";// we need the new record to have a new timestamp
mysql_query($sql);
$sql = "SELECT MAX(tableId) FROM table";
$res = mysql_query($sql);
$row = mysql_fetch_row($res);
return $row[0];//gives the new ID from auto incrementing
}

Some of the following was gleaned off of this site. This is what I did to duplicate a record in a table with any number of fields:

This also assumes you have an AI field at the beginning of the table

function duplicateRow( $id = 1 ){
dbLink();//my db connection
$qColumnNames = mysql_query("SHOW COLUMNS FROM table") or die("mysql error");
$numColumns = mysql_num_rows($qColumnNames);

for ($x = 0;$x < $numColumns;$x++){
$colname[] = mysql_fetch_row($qColumnNames);
}

$sql = "SELECT * FROM table WHERE tableId = '$id'";
$row = mysql_fetch_row(mysql_query($sql));
$sql = "INSERT INTO table SET ";
for($i=1;$i<count($colname)-4;$i++){//i set to 1 to preclude the id field
//we set count($colname)-4 to avoid the last 4 fields (good for our implementation)
$sql .= "`".$colname[$i][0]."`  =  '".$row[$i]. "', ";
}
$sql .= " CreateTime = NOW()";// we need the new record to have a new timestamp
mysql_query($sql);
$sql = "SELECT MAX(tableId) FROM table";
$res = mysql_query($sql);
$row = mysql_fetch_row($res);
return $row[0];//gives the new ID from auto incrementing
}
冷清清 2024-10-06 20:57:42

我可能会迟到,但我有一个对我有用的类似解决方案。

 INSERT INTO `orders` SELECT MAX(`order_id`)+1,`container_id`, `order_date`, `receive_date`, `timestamp` FROM `orders` WHERE `order_id` = 1

这样我就不需要创建临时表等。由于行被复制到同一个表中,因此可以轻松使用 Max(PK)+1 函数。

我来寻找这个问题的解决方案(忘记了语法),最后我做了自己的查询。有时事情的进展很有趣。

问候

I might be late in this, but I have a similar solution which has worked for me.

 INSERT INTO `orders` SELECT MAX(`order_id`)+1,`container_id`, `order_date`, `receive_date`, `timestamp` FROM `orders` WHERE `order_id` = 1

This way I don't need to create a temporary table and etc. As the row is copied in the same table the Max(PK)+1 function can be used easily.

I came looking for the solution of this question (had forgotten the syntax) and I ended up making my own query. Funny how things work out some times.

Regards

中二柚 2024-10-06 20:57:42

如果主键是自增,则只需指定除主键外的各个字段即可。

插入表(字段1,字段2,字段3)
从表中选择(字段1,字段2,字段3)
WHERE 主键=1

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

寂寞清仓 2024-10-06 20:57:42

我更新了@LeonardChallis 的解决方案,因为它对我不起作用,其他人也没有。我删除了临时表中的WHERE子句和SET PrimaryKey = 0,这样MySQL就会自动增加primaryKey,

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

这当然是复制all表中的行。

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.

勿忘初心 2024-10-06 20:57:41

我使用了 Leonard Challis 的技术,并进行了一些更改:

CREATE TEMPORARY TABLE tmptable_1 SELECT * FROM table WHERE primarykey = 1;
UPDATE tmptable_1 SET primarykey = NULL;
INSERT INTO table SELECT * FROM tmptable_1;
DROP TEMPORARY TABLE IF EXISTS tmptable_1;

作为临时表,永远不应该有超过一条记录,因此您不必担心主键。将其设置为 null 允许 MySQL 自行选择值,因此不存在创建重复项的风险。

如果您想非常确定只插入一行,可以将 LIMIT 1 添加到 INSERT INTO 行的末尾。

请注意,我还将主键值(在本例中为 1)附加到临时表名称中。

I used Leonard Challis's technique with a few changes:

CREATE TEMPORARY TABLE tmptable_1 SELECT * FROM table WHERE primarykey = 1;
UPDATE tmptable_1 SET primarykey = NULL;
INSERT INTO table SELECT * FROM tmptable_1;
DROP TEMPORARY TABLE IF EXISTS tmptable_1;

As a temp table, there should never be more than one record, so you don't have to worry about the primary key. Setting it to null allows MySQL to choose the value itself, so there's no risk of creating a duplicate.

If you want to be super-sure you're only getting one row to insert, you could add LIMIT 1 to the end of the INSERT INTO line.

Note that I also appended the primary key value (1 in this case) to my temporary table name.

_蜘蛛 2024-10-06 20:57:41

更新 07/07/2014 - 基于我的答案(Grim...)的答案是一个更好的解决方案,因为它改进了我下面的解决方案,所以我建议使用它。

您可以使用以下语法来执行此操作,而无需列出所有列:

CREATE TEMPORARY TABLE tmptable SELECT * FROM table WHERE primarykey = 1;
UPDATE tmptable SET primarykey = 2 WHERE primarykey = 1;
INSERT INTO table SELECT * FROM tmptable WHERE primarykey = 2;

您可以决定以其他方式更改主键。

Update 07/07/2014 - The answer based on my answer, by Grim..., is a better solution as it improves on my solution below, so I'd suggest using that.

You can do this without listing all the columns with the following syntax:

CREATE TEMPORARY TABLE tmptable SELECT * FROM table WHERE primarykey = 1;
UPDATE tmptable SET primarykey = 2 WHERE primarykey = 1;
INSERT INTO table SELECT * FROM tmptable WHERE primarykey = 2;

You may decide to change the primary key in another way.

只是在用心讲痛 2024-10-06 20:57:41

我假设您希望新记录有一个新的主键?如果 primarykeyAUTO_INCRMENT 则只需执行以下操作:

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

...其中 col1, col2, col3, ... 是表除了 主键

如果它不是 AUTO_INCRMENT 列,并且您希望能够为 primarykey 选择新值,则类似:

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

...其中 567primarykey 的新值。

I'm assuming you want the new record to have a new primarykey? If primarykey is AUTO_INCREMENT then just do this:

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

...where col1, col2, col3, ... is all of the columns in the table except for primarykey.

If it's not an AUTO_INCREMENT column and you want to be able to choose the new value for primarykey it's similar:

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

...where 567 is the new value for primarykey.

小傻瓜 2024-10-06 20:57:41

您几乎在第一个查询中就完成了,您只需要指定列,这样您就可以在插入中排除您的主键,这将在表上执行您可能拥有的自动增量,以自动为该表创建一个新的主键入口。

例如,将其更改为:

insert into table select * from table where primarykey=1

对此:

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

只需不在查询的 INSERT 或 SELECT 部分的列列表中包含主键列即可。

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.

街道布景 2024-10-06 20:57:41

您还可以尝试转储表,找到插入命令并对其进行编辑:

mysqldump -umyuser -p mydatabase --skip-extended-insert mytable > outfile.sql

--skip-extended-insert 为您提供每行一个插入命令。然后,您可以在您最喜欢的文本编辑器中找到该行,提取命令并将主键更改为“默认”。

You could also try dumping the table, finding the insert command and editing it:

mysqldump -umyuser -p mydatabase --skip-extended-insert mytable > outfile.sql

The --skip-extended-insert gives you one insert command per row. You may then find the row in your favourite text editor, extract the command and alter the primary key to "default".

温柔嚣张 2024-10-06 20:57:41

这可以通过一些创造性来实现:

SET @sql = CONCAT('INSERT INTO <table> SELECT null, 
    ', (SELECT GROUP_CONCAT(COLUMN_NAME) 
    FROM information_schema.columns 
    WHERE table_schema = '<database>' 
    AND table_name = '<table>' 
    AND column_name NOT IN ('id')), ' 
from <table> WHERE id = <id>');  

PREPARE stmt1 FROM @sql;
EXECUTE stmt1;

这将导致新行获得自动递增的 id,而不是所选行的 id。

This can be achieved with some creativity:

SET @sql = CONCAT('INSERT INTO <table> SELECT null, 
    ', (SELECT GROUP_CONCAT(COLUMN_NAME) 
    FROM information_schema.columns 
    WHERE table_schema = '<database>' 
    AND table_name = '<table>' 
    AND column_name NOT IN ('id')), ' 
from <table> WHERE id = <id>');  

PREPARE stmt1 FROM @sql;
EXECUTE stmt1;

This will result in the new row getting an auto incremented id instead of the id from the selected row.

怪我闹别瞎闹 2024-10-06 20:57:41

此过程假设:

  • 您没有 _duplicate_temp_table
  • 您的主键是 int
  • 您有权创建表

当然这并不完美,但在某些(可能是大多数)情况下它会起作用。

DELIMITER $
CREATE PROCEDURE DUPLICATE_ROW(copytable VARCHAR(255), primarykey VARCHAR(255), copyid INT, out newid INT)
BEGIN
        DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @error=1;
        SET @temptable = '_duplicate_temp_table';
        SET @sql_text = CONCAT('CREATE TABLE ', @temptable, ' LIKE ', copytable);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('INSERT INTO ', @temptable, ' SELECT * FROM ', copytable, ' where ', primarykey,'=', copyid);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('SELECT max(', primarykey, ')+1 FROM ', copytable, ' INTO @newid');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('UPDATE ', @temptable, ' SET ', primarykey, '=@newid');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('INSERT INTO ', copytable, ' SELECT * FROM ', @temptable, '');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('DROP TABLE ', @temptable);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SELECT @newid INTO newid;
END $
DELIMITER ;

CALL DUPLICATE_ROW('table', 'primarykey', 1, @duplicate_id);
SELECT @duplicate_id;

This procedure assumes that:

  • you don't have _duplicate_temp_table
  • your primary key is int
  • you have access to create table

Of course this is not perfect, but in certain (probably most) cases it will work.

DELIMITER $
CREATE PROCEDURE DUPLICATE_ROW(copytable VARCHAR(255), primarykey VARCHAR(255), copyid INT, out newid INT)
BEGIN
        DECLARE EXIT HANDLER FOR SQLEXCEPTION SET @error=1;
        SET @temptable = '_duplicate_temp_table';
        SET @sql_text = CONCAT('CREATE TABLE ', @temptable, ' LIKE ', copytable);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('INSERT INTO ', @temptable, ' SELECT * FROM ', copytable, ' where ', primarykey,'=', copyid);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('SELECT max(', primarykey, ')+1 FROM ', copytable, ' INTO @newid');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('UPDATE ', @temptable, ' SET ', primarykey, '=@newid');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('INSERT INTO ', copytable, ' SELECT * FROM ', @temptable, '');
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SET @sql_text = CONCAT('DROP TABLE ', @temptable);
        PREPARE stmt FROM @sql_text;
        EXECUTE stmt;
        DEALLOCATE PREPARE stmt;
        SELECT @newid INTO newid;
END $
DELIMITER ;

CALL DUPLICATE_ROW('table', 'primarykey', 1, @duplicate_id);
SELECT @duplicate_id;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文