复制行但使用新 ID

分享于2022年07月17日 mysql 问答
【问题标题】:复制行但使用新 ID(Copy row but with new id)
【发布时间】:2022-05-09 19:31:54
【问题描述】:

我有一个表“test”,其中包含自动递增的 id 和任意数量的列。

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

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

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

  • @JohnP 不,它不是重复的。 OP 不想使用 ON DUPLICATE ... ,而被推荐的帖子使用 update ,这是 OP 不想要的。
  • @Ravinder - OP 在哪里说他不想更新?提到的帖子正是他想要做的。复制一行而不命名所有列。
  • @JohnP OP 说“ ...直到我意识到它永远不会在重复时插入,它只是更新现有行。
  • 而且,如果您真的阅读了引用的帖子,第二个问题就是答案,使用临时表。如果不命名所有列,您将无法做到这一点,这是 OP 不想要的。临时表,插入行,更新 id,重新插入第一个表。

【解决方案1】:

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

( 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 字段生成一个新值,并从选定行的 col1 col2 复制值。

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

更新
对 JohnP 和 Martin 的 cmets 表示敬意 -

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

参考 Tim Ruehsen referred posting 中的回答:

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;

希望这会有所帮助。

  • 但是这里你说的是要复制哪些列。我不想只知道主键的名称来做到这一点。
  • 这是非常正确的。当您创建像“CREATE TEMPORARY TABLE tmp SELECT * from my_table WHERE ...;”这样的表时,它不会创建主键以及其他键,并且不会填充此临时表的“AUTO_INCREMENT”值。而且它不会自动递增字段。然而,它确实为该字段保存了可为空的参数,这就是为什么最好删除它。
  • 大警告!! ALTER TABLE 会导致隐式事务提交,即使它位于临时表上。而且,实际上,您应该使用 DROP TEMPORARY TABLE tmp; 来避免在最后一行出现同样的情况,尽管到那时为时已晚。
  • 如果我们想添加自定义 col 值和从前一行复制的其他值怎么办?
  • @CrackIt:上面的思考过程只是复制记录,没有提及列名或表达式。但是,对于自定义列值,您需要使用列名。