例如,当我删除 id 3 时,我有这个:
id | name
1 |
2 |
4 |
5 |
...
现在,我想搜索丢失的 id,因为我想再次填充 id:
INSERT INTO xx (id,...) VALUES (3,...)
有没有办法在 auto_increment 索引中搜索“洞”?
谢谢!
例如,当我删除 id 3 时,我有这个:
id | name
1 |
2 |
4 |
5 |
...
现在,我想搜索丢失的 id,因为我想再次填充 id:
INSERT INTO xx (id,...) VALUES (3,...)
有没有办法在 auto_increment 索引中搜索“洞”?
谢谢!
您可以像这样找到差距的最高值:
select t1.id - 1 as missing_id
from mytable t1
left join mytable t2 on t2.id = t1.id - 1
where t2.id is null
的目的AUTO_INCREMENT
是为您的行生成简单的唯一且无意义的标识符。一旦您计划重新使用这些 ID,它们就不再是唯一的(至少在时间上如此),所以我的印象是您没有使用正确的工具来完成这项工作。如果您决定摆脱AUTO_INCREMENT
,则可以使用相同的算法进行所有插入。
关于 SQL 代码,此查询将现有行与具有下一个 ID 的行匹配:
SELECT a.foo_id, b.foo_id
FROM foo a
LEFT JOIN foo b ON a.foo_id=b.foo_id-1
例如:
1 NULL
4 NULL
10 NULL
12 NULL
17 NULL
19 20
20 NULL
24 25
25 26
26 27
27 NULL
所以很容易过滤掉行并得到第一个间隙:
SELECT MIN(a.foo_id)+1 AS next_id
FROM foo a
LEFT JOIN foo b ON a.foo_id=b.foo_id-1
WHERE b.foo_id IS NULL
以此为起点,因为它仍然需要一些调整:
我认为你可以做到这一点的唯一方法是使用循环:任何其他解决方案都不会显示大于 1 的间隙:
insert into XX values (1)
insert into XX values (2)
insert into XX values (4)
insert into XX values (5)
insert into XX values (10)
declare @min int
declare @max int
select @min=MIN(ID) from xx
select @max=MAX(ID) from xx
while @min<@max begin
if not exists(select 1 from XX where id = @min+1) BEGIN
print 'GAP: '+ cast(@min +1 as varchar(10))
END
set @min=@min+1
end
结果:
GAP: 3
GAP: 6
GAP: 7
GAP: 8
GAP: 9
首先,我同意你不应该尝试填补漏洞的评论。您将无法通过一条 SQL 语句找到所有漏洞。您必须遍历从 1 开始的所有可能的数字,直到找到一个洞。您可以编写一个 sql 函数来为您执行此操作,然后可以在函数中使用它。因此,如果您编写了一个名为 find_first_hole 的函数,则可以在插入中调用它,例如:
INSERT INTO xx (id, ...) VALUES (find_first_hole(), ...)