2011-12-30 32 views
0

我正在尝试重复行在同一个表中。表A有没有auto_increment(不幸)。重新评估每个INSERT的MySQL子查询

INSERT INTO A (id, foreign_id, value) 
    SELECT (SELECT MAX(id)+1 FROM A), 2, value 
     FROM A WHERE foreign_id = 1; 

(SELECT MAX(id)+1 FROM A)计算一次,所以它总是会返回相同的ID。在第二行插入查询将失败(重复的主键)。

我想,第一:

INSERT INTO A (id, foreign_id, value) 
    SELECT MAX(id)+1, 2, value 
     FROM A WHERE foreign_id = 1; 

但是,MAX(id)+1考虑WHERE foreign_id = 1,所以没有保证,我会得到一个未使用的ID。

我如何可以继续之一:

  • 有重新计算每个INSERT
  • 或更一般的子查询:复制给我的表行有否auto_increment
+0

使用'max(id)+ 1'生成一个唯一的号码在多用户系统中肯定会失败。您应该使用自动增量列来代替 – 2011-12-30 11:26:50

+0

我正确的是,您并未真正复制,您尝试使用不同的ID创建单独的记录,并且使用的foreign_ID为2,但与具有1的foreign_ID的记录具有相同的值?所以如果你有以下2条记录:{1,1,1} {3,1,2}你想要一个新的集合{4,2,1}和{5,2,2}?如果是这样,你想要“复制”多少条记录,他们是否必须按照现有的记录顺序?而不是{4,2,1}和{5,2,2}将{4,2,1}和{6,2,2}?工作? – xQbert 2011-12-30 11:30:54

+0

@a_horse_with_no_name是的我知道,这只是一个大脚本,没有多用户或任何东西。 – 2011-12-30 11:30:59

回答

2

你有没有尝试过使用变量?

SET @max=SELECT MAX(id); 
INSERT INTO A (id, foreign_id, value) 
    SELECT @max:[email protected]+1, 2, value 
     FROM A WHERE foreign_id = 1; 
+0

谢谢你做的伎俩,第一次使用变量。如果在接受答案之前有其他可能的解决方案,我会再给它一点时间。 – 2011-12-30 11:33:26

+0

无论如何你都欢迎 – gotofritz 2011-12-30 11:35:38

1

根据评论我相信这会工作。 诀窍是你不能像你发现的那样使用+1(除非你使用变量),但是你可以使用现有的ID并将它添加到max中,每次都会给你一个唯一的ID。

INSERT INTO A (id, foreign_id, value) 
    SELECT (SELECT MAX(id) FROM A)+ID, 2, value 
     FROM A WHERE foreign_id = 1; 
+0

IMO:fritzfromLondon的答案是更好的,如果你想保持序列无间距。矿井将保留与现有记录相似的间距(因为存在间隙,并且由于某种原因,您希望维护它们) – xQbert 2011-12-30 11:40:10

+0

有趣的是,这很简单,即使我要小心达到列类型允许的最大数量。 – 2011-12-30 12:18:51