在同一MySQL表中复制/复制记录

Dig*_*its 84 mysql

我一直在寻找一段时间但我无法找到解决问题的简单方法.我想在表中复制记录,但当然,需要更新唯一的主键.

我有这个问题:

INSERT INTO invoices
    SELECT * FROM invoices AS iv WHERE iv.ID=XXXXX
    ON DUPLICATE KEY UPDATE ID = (SELECT MAX(ID)+1 FROM invoices)
Run Code Online (Sandbox Code Playgroud)

问题是这只是改变ID了行而不是复制行.有人知道如何解决这个问题吗?

//编辑:我想在不输入所有字段名称的情况下执行此操作,因为字段名称可能会随时间而变化.

小智 130

我通常采用的方式是使用临时表.它可能没有计算效率,但似乎工作正常!在这里,我完整地复制记录99,创造了100记录.

CREATE TEMPORARY TABLE tmp SELECT * FROM invoices WHERE id = 99;

UPDATE tmp SET id=100 WHERE id = 99;

INSERT INTO invoices SELECT * FROM tmp WHERE id = 100;
Run Code Online (Sandbox Code Playgroud)

希望对你有用!

  • 您可以使用NULL:`CREATE TEMPORARY TABLE tmp SELECT bla FROM Invoices WHERE bla; UPDATE tmp SET id = NULL; INSERT INTO发票SELECT*FROM tmp;` (6认同)
  • 如果您要复制单个记录,则可以删除更新和插入中的位置.然后你可以在mysql控制台中按两次,这将显示历史记录中的最后一个操作,在更新中更改id,最后方便,按Enter键,按下,再次按Enter键而不更改任何内容,然后重复多份副本的程序.快多了. (4认同)
  • 如果id 100已经存在的话.如果您为新行选择任何新ID,并且在操作期间其他人插入新行,那么您的ID和新插入的ID将是相同的.这是这段代码中的瓶颈. (4认同)

小智 80

Alex的答案需要在多客户端环境中进行一些关注(例如锁定或事务).

假设该AUTO ID字段是表中的第一个字段(通常情况),我们可以使用隐式事务.

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

来自MySQL文档:

使用AUTO_INCREMENT:您还可以显式为列分配NULL或0以生成序列号.


Ing*_*ngo 11

你肯定知道,DUPLICATE KEY会触发,因此你可以事先选择MAX(ID)+1:

INSERT INTO invoices SELECT MAX(ID)+1, ... other fields ... FROM invoices AS iv WHERE iv.ID=XXXXX 
Run Code Online (Sandbox Code Playgroud)

  • 是的,但我不想输入所有其他字段(大约有 20 个,它们可能会随着时间的推移而改变)。我不想在每次 tablestructre 更改时更改代码。 (2认同)

Per*_*are 11

您的方法很好,但问题是您使用"*"而不是登记字段名称.如果您将所有列名称除了主键,则您的脚本将在一个或多个记录上像魅力一样工作.

INSERT INTO invoices (iv.field_name, iv.field_name,iv.field_name ) SELECT iv.field_name, iv.field_name,iv.field_name FROM invoices AS iv WHERE iv.ID=XXXXX


Al-*_*far 7

我知道一个迟到的答案,但它仍然是一个常见问题,我想添加另一个答案,它对我有用,只使用单行insert into语句,我认为它是直接的,没有创建任何新表(因为它可能是CREATE TEMPORARY TABLE权限问题):

INSERT INTO invoices (col_1, col_2, col_3, ... etc)
  SELECT
    t.col_1,
    t.col_2,
    t.col_3,
    ...
    t.updated_date,
  FROM invoices t;
Run Code Online (Sandbox Code Playgroud)

解决方案适用于AUTO_INCREMENTid列,否则,您也可以ID在语句中添加列:

INSERT INTO invoices (ID, col_1, col_2, col_3, ... etc)
  SELECT
    MAX(ID)+1,
    t.col_1,
    t.col_2,
    t.col_3,
    ... etc ,
  FROM invoices t;
Run Code Online (Sandbox Code Playgroud)

它非常容易和直接,您可以在一行中更新任何其他内容而无需任何第二个更新语句供以后使用(例如:使用额外文本更新标题列或用另一个更换字符串),您也可以具体说明确切地说你想要复制,如果它是,如果有的话,你可以这样做.

  • 这也是在复制时修改某些字段的良好基础.我刚刚使用`INSERT进入wp_options SELECT NULL,'theme_mods_twopress',option_value,自动加载FROM wp_options,其中option_name ='theme_mods_onepress';`复制同时增加条目(`AUTO_INCREMENT``BULL`技巧从上面开始)和`option_name`字段同样. (2认同)