在同一个MySQL表中复制/复制logging
我一直在寻找一段时间,但我找不到解决我的问题的简单方法。 我想重复一个表中的logging,但当然,唯一的主键需要更新。
我有这个查询:
INSERT INTO invoices SELECT * FROM invoices AS iv WHERE iv.ID=XXXXX ON DUPLICATE KEY UPDATE ID = (SELECT MAX(ID)+1 FROM invoices)
问题是这只是改变行的ID
而不是复制行。 有谁知道如何解决这个问题?
//编辑:我想这样做,而不键入所有的字段名称,因为字段名称可以随时间而改变。
我通常使用临时表的方式。 这可能不是计算效率高,但它似乎工作正常! 在这里,我完整地复制了99条logging,创造了100条logging。
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;
希望能为你工作好!
Alex的回答在多客户端环境中需要谨慎(例如locking或事务)。
假设AUTO ID
字段是表中的第一个(通常情况下),我们可以使用隐式事务。
CREATE TEMPORARY TABLE tmp SELECT * from invoices WHERE ...; ALTER TABLE tmp drop ID; #删除自动增量字段 #UPDATE tmp SET ...; #只需要更改其他唯一键 INSERT INTO invoices SELECT 0,tmp。* FROM tmp; DROP TABLE tmp;
从MySQL文档:
使用AUTO_INCREMENT:您也可以显式地将NULL或0分配给列来生成序列号。
您肯定知道,DUPLICATE KEY将触发,因此您可以事先selectMAX(ID)+1:
INSERT INTO invoices SELECT MAX(ID)+1, ... other fields ... FROM invoices AS iv WHERE iv.ID=XXXXX
你的方法是好的,但问题是你使用“*”,而不是登记字段名称。 如果你把所有列名称的主键,你的脚本将像一个或多个logging上的魅力。
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
我也需要这个; 我的解决scheme是使用SQLYOG(免费版)导出所需的logging作为SQL(创build一个插入)。
然后我手编辑这个删除id,因为这需要自动生成,然后复制插入到SQLYog执行它。 这是无痛的。 我猜大量的其他MySQL GUI也可以做到这一点。
这为我提供了一个logging,可以用于实时系统的testing。
我现在有这个插入以供重用,因为这个表每天都被重写。
我有一个类似的问题,这是我正在做的重要
insert into Preguntas (`EncuestaID`, `Tipo` , `Seccion` , `RespuestaID` , `Texto` ) select '23', `Tipo`, `Seccion`, `RespuestaID`, `Texto` from Preguntas where `EncuestaID`= 18
已经是Preguntas:
CREATE TABLE IF NOT EXISTS `Preguntas` ( `ID` int(11) unsigned NOT NULL AUTO_INCREMENT, `EncuestaID` int(11) DEFAULT NULL, `Tipo` char(5) COLLATE utf8_unicode_ci DEFAULT NULL, `Seccion` int(11) DEFAULT NULL, `RespuestaID` bigint(11) DEFAULT NULL, `Texto` text COLLATE utf8_unicode_ci , PRIMARY KEY (`ID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=522 ;
所以, ID
自动增加,我也使用EncuestaID固定值('23')
我只是想扩展Alex伟大的答案,如果你想重复一整套logging,
SET @x=7; CREATE TEMPORARY TABLE tmp SELECT * FROM invoices; UPDATE tmp SET id=id+@x; INSERT INTO invoices SELECT * FROM tmp;
我只需要做到这一点,发现亚历克斯的答案是一个完美的起点! 当然,你必须将@x设置为表格中最高的行号(我相信你可以通过查询来获取)。 这只在这个非常具体的情况下才有用,所以当你不想复制所有的行时要小心使用它。 根据需要调整math。
我知道一个迟到的答案,但它仍然是一个常见的问题,我想补充另一个答案,它为我工作,只使用单行insert into
语句,我认为这是直接的,没有创build任何新表(因为这可能是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;
该解决scheme正在为AUTO_INCREMENT
ID列工作,否则,您还可以添加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;
它非常简单直接,你可以在一行中更新其他任何东西,而不需要任何第二个更新语句(例如:用额外的文本更新标题列或用另一个stringreplacestring),也可以具体说明什么正好你想要复制,如果一切都那么,如果有的话,你可以这样做。
稍有不同,主要区别在于将主键字段(“varname”)设置为null,这会产生警告,但会起作用。 通过将主键设置为null,在最后一条语句中插入logging时,自动递增工作。
这段代码也清理了以前的尝试,并且可以不止一次运行而没有问题:
DELETE FROM `tbl` WHERE varname="primary key value for new record"; DROP TABLE tmp; CREATE TEMPORARY TABLE tmp SELECT * FROM `tbl` WHERE varname="primary key value for old record"; UPDATE tmp SET varname=NULL; INSERT INTO `tbl` SELECT * FROM tmp;