我最近继承了一个数据库,其中一个表的主键由编码值组成(Part1*1000 + Part2).
我将该列标准化,但我无法更改旧值.所以现在我有
select ID from table order by ID ID 100001 100002 101001 ...
我想找到表格中的"洞"(更准确地说,是100000之后的第一个"洞").
我正在使用以下选择,但是有更好的方法吗?
select /* top 1 */ ID+1 as newID from table where ID > 100000 and ID + 1 not in (select ID from table) order by ID newID 100003 101029 ...
该数据库是Microsoft SQL Server 2000.我可以使用SQL扩展.
select ID +1 From Table t1 where not exists (select * from Table t2 where t1.id +1 = t2.id);
不确定这个版本是否会比你原先提到的版本更快.
SELECT (ID+1) FROM table AS t1 LEFT JOIN table as t2 ON t1.ID+1 = t2.ID WHERE t2.ID IS NULL
此解决方案应该为您提供您正在寻找的"洞"的第一个和最后一个ID值.我在Firebird 1.5中使用这个500K记录的表,虽然它确实需要一段时间,它给了我想要的东西.
SELECT l.id + 1 start_id, MIN(fr.id) - 1 stop_id FROM (table l LEFT JOIN table r ON l.id = r.id - 1) LEFT JOIN table fr ON l.id < fr.id WHERE r.id IS NULL AND fr.id IS NOT NULL GROUP BY l.id, r.id
例如,如果您的数据如下所示:
ID 1001 1002 1005 1006 1007 1009 1011
你会收到这个:
start_id stop_id 1003 1004 1008 1008 1010 1010
我希望我能完全赞同这个解决方案,但我在Xaprb找到了它.