我一直在寻找一段时间但我无法找到解决问题的简单方法.我想在表中复制记录,但当然,需要更新唯一的主键.
我有这个问题:
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)
希望对你有用!
小智 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)
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
我知道一个迟到的答案,但它仍然是一个常见问题,我想添加另一个答案,它对我有用,只使用单行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)
它非常容易和直接,您可以在一行中更新任何其他内容而无需任何第二个更新语句供以后使用(例如:使用额外文本更新标题列或用另一个更换字符串),您也可以具体说明确切地说你想要复制,如果它是,如果有的话,你可以这样做.