70

我有一个自动递增id和任意数量的列的表“测试”。

我想在这个表中复制一行,除了id当然之外,所有列都相同。

有没有办法在不命名所有列的情况下做到这一点?

我认为INSERT... SELECT... ON DUPLICATE KEY会帮助我,直到我意识到它永远不会生成INSERT ON DUPLICATE,它只是更新现有的行。

4

6 回答 6

112

假设您的表具有以下字段:

( pk_id int not null auto_increment primary key,
  col1 int,
  col2 varchar(10)
)

然后,要将值从一行复制到具有新键值的另一行,以下查询可能会有所帮助

insert into my_table( col1, col2 ) select col1, col2 from my_table where pk_id=?;

这将为字段生成一个新值,并pk_id从 和 复制所选行的值。col1col2

您可以扩展此示例以应用表中的更多字段。

更新
充分尊重 JohnP 和 Martin 的评论-

我们可以使用临时表先从主表缓冲,然后再用它复制到主表。仅更新临时表中的 pk 引用字段将无济于事,因为它可能已经存在于主表中。相反,我们可以从临时表中删除 pk 字段并将所有其他字段复制到主表中。

参考Tim Ruehsen参考帖子中的回答:

CREATE TEMPORARY TABLE tmp SELECT * from my_table WHERE ...;
ALTER TABLE tmp drop pk_id; # drop autoincrement field
# UPDATE tmp SET ...; # just needed to change other unique keys
INSERT INTO my_table SELECT 0,tmp.* FROM tmp;
DROP TEMPORARY TABLE tmp;

希望这可以帮助。

于 2012-07-04T15:09:31.493 回答
5

这适用于 MySQL 所有版本和 Amazon RDS Aurora:

INSERT INTO my_table SELECT 0,tmp.* FROM tmp;

或者

将索引列设置为 NULL,然后执行 INSERT。

但不是在 MariaDB 中,我测试了版本 10。

于 2015-07-08T15:54:39.047 回答
3

这仅适用于复制一行

  • 从您的表中选择您的一行
  • 获取所有关联
  • 取消设置 ID 行(唯一索引键)
  • 将数组 [0] 键内嵌到列名中
  • 将数组 [0] 值内嵌到列值中
  • 运行查询

编码:

 $qrystr = "SELECT * FROM mytablename  WHERE id= " . $rowid;
 $qryresult = $this->connection->query($qrystr);
 $result = $qryresult->fetchAll(PDO::FETCH_ASSOC);
 unset($result[0]['id']); //Remove ID from array
 $qrystr = " INSERT INTO mytablename";
 $qrystr .= " ( " .implode(", ",array_keys($result[0])).") ";
 $qrystr .= " VALUES ('".implode("', '",array_values($result[0])). "')";
 $result = $this->connection->query($qrystr);
 return $result;

当然你应该使用 PDO:bindparam 并检查你的变量是否受到攻击等,但给出了例子

附加信息

如果您在处理NULL值时遇到问题,您可以使用以下代码,以便imploding名称和值仅适用于其值不是NULL.

foreach ($result[0] as $index => $value) {
    if ($value === null) unset($result[0][$index]);
}
于 2014-05-26T20:02:34.973 回答
2
SET @table = 'the_table';
SELECT GROUP_CONCAT(IF(COLUMN_NAME IN ('id'), 0, CONCAT("\`", COLUMN_NAME, "\`"))) FROM INFORMATION_SCHEMA.COLUMNS
                  WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = @table INTO @columns;
SET @s = CONCAT('INSERT INTO ', @table, ' SELECT ', @columns,' FROM ', @table, ' WHERE id=1');
PREPARE stmt FROM @s;
EXECUTE stmt;
于 2020-06-26T11:58:52.263 回答
1

根据有多少列,您可以只命名列,不使用 ID,然后手动添加一个 ID,或者,如果它在您的表中,则添加一个辅助 ID (sid):

insert into PROG(date, level, Percent, sid) select date, level, Percent, 55 from PROG where sid = 31 在这里,如果 sid 31 有多个结果行,所有这些都将被复制到 sid 55 并且您的自动 ID 仍将自动生成。仅用于 ID: insert into PROG(date, level, Percent, ID) select date, level, Percent, 55 from PROG where ID = 31 其中 55 是表中的下一个可用 ID,ID 31 是您要复制的 ID。

于 2019-04-25T11:40:41.260 回答
-1
INSERT into table_name (  
    `product_id`, 
    `other_products_url_id`, 
    `brand`, 
    `title`, 
    `price`, 
    `category`, 
    `sub_category`, 
    `quantity`, 
    `buy_now`, 
    `buy_now_url`, 
    `is_available`, 
    `description`, 
    `image_url`, 
    `image_type`, 
    `server_image_url`, 
    `reviews`, 
    `hits`, 
    `rating`, 
    `seller_name`, 
    `seller_desc`, 
    `created_on`, 
    `modified_on`, 
    `status`) 
SELECT 
    `product_id`, 
    `other_products_url_id`, 
    `brand`, 
    `title`, 
    `price`, 
    `category`, 
    `sub_category`, 
    `quantity`, 
    `buy_now`, 
    concat(`buy_now_url`,'','#test123456'), 
    `is_available`, 
    `description`, 
    `image_url`, 
    `image_type`, 
    `server_image_url`, 
    `reviews`, 
    `hits`, 
    `rating`, 
    `seller_name`, 
    `seller_desc`, 
    `created_on`, 
    `modified_on`, 
    `status` 
FROM `table_name` WHERE id='YourRowID';
于 2015-11-27T13:04:43.430 回答