In MySQL, can I copy one row to insert into the same table?

后端 未结 26 2141
-上瘾入骨i
-上瘾入骨i 2020-11-27 09:56
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 ex

相关标签:
26条回答
  • 2020-11-27 10:20

    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

    0 讨论(0)
  • 2020-11-27 10:21

    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`;
    
    0 讨论(0)
  • 2020-11-27 10:22

    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__);
    }
    
    0 讨论(0)
  • 2020-11-27 10:23

    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.

    0 讨论(0)
  • 2020-11-27 10:25

    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.

    0 讨论(0)
  • 2020-11-27 10:25

    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();
    
    0 讨论(0)
提交回复
热议问题