我有一个主键表(其名称为" id")定义为auto_increment。我在INSERT语句中使用NULL来"填充" id值。当然,它有效。但是现在我需要"移动"现有记录到新的主键值(下一个可用,值不是那么重要,但它必须是新的,如果按id排序则是最后一个)。我怎么能在一个优雅的"办法?因为"在INSERT"处使用NULL使用UPDATE不起作用太多:
update idtest set id=NULL where id=1;
这只会使记录的id为零。我希望与INSERT做同样的事情,但似乎我的想法不正确。
当然我可以使用" INSERT ... SELECT"语句,然后旧的DELETE,或者我可以使用像MAX(id)+ 1这样的东西在一步中更新旧记录的ID等,但我很好奇是否有更好的解决方案。
此外,MAX(id)解决方案似乎无法正常工作:
mysql> update idtest set id=max(id)+1 where id=3;
ERROR 1111 (HY000): Invalid use of group function
mysql> update idtest set id=(select max(id)+1 from idtest) where id=3;
ERROR 1093 (HY000): You can't specify target table 'idtest' for update in FROM clause
答案 0 :(得分:3)
这是我相信的方式:
UPDATE users SET id = (SELECT `AUTO_INCREMENT`
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test'
AND TABLE_NAME = 'users') WHERE id = 2;
select * from users;
我用自己的表替代你的。
test
是数据库名称,在我的情况下,users
是表名,id
是AUTO_INCREMENT
。
编辑:上面的我的查询工作完美,但其副作用有些“危险”,下次插入时AUTO_INCREMENT
值将与最近更新的记录发生冲突,因此下一次插入将失败。为了避免这种情况,我将上述查询修改为了一个事务:
START transaction;
UPDATE users SET id = (SELECT `AUTO_INCREMENT`
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'test'
AND TABLE_NAME = 'users') WHERE id = 2;
#renew auto increment to avoid duplicate warning on next insert
INSERT IGNORE INTO users(username) values ('');
COMMIT
希望如果不是OP,这将有助于某人。
答案 1 :(得分:2)
您尝试更新同一个表的方式有误,但您可以在同一个表上使用连接
update idtest t
join (select id +1 as id
from idtest order by id desc
limit 1) t1
set t.id=t1.id
where t.id=3;
或
update idtest t
join (select max(id) +1 as id
from idtest ) t1
set t.id=t1.id
where t.id=3;
答案 2 :(得分:1)
您可以使用REPLACE INTO
子句来执行此操作。
从手册:
REPLACE的工作原理与INSERT完全相同,只是如果表中的旧行与PRIMARY KEY或UNIQUE索引的新行具有相同的值,则在插入新行之前删除旧行。请参见第13.2.5节“INSERT语法”。
修改强> 我的错误(在评论中)你必须有两个独特的约束才能实现这个目标:
当你使用auto_increment值来替换记录时,记录将被替换为给定ID并且不会改变(但是AI值会增加)。
您必须从查询中排除AI列。如果你还有一个UQ约束,你可以这样做。
检查此SQLFiddle演示:http://sqlfiddle.com/#!2/1a702e
第一个查询将替换所有记录(但id的值不会更改)。
第二个也将替换它,并将使用新的AI值。 (请注意,第二个查询不包含id
列,并且some
列上存在UQ约束。
您可以注意到,第二个查询使用的AI值高于排除的值:这是因为第一个替换增加了AI值。
如果没有两个唯一键(一个用于AI,另一个用于另一列),则REPLACE语句将作为普通的INSERT语句使用!
(当然,您可以使用PRIMARY KEY更改其中一个UNIQUE KEY)