mysql – 如何按行顺序获取缺失值?

在一个表中,已经删除了很多行,如何获取下一个INSERT缺少行的id?

例如

id      col1
1       1
3       3
4       4
5       5
8       8
9       9

如何获取下一个INSERT的第一个可用ID的值.在这里,我想得到id = 2.

就像是

SELECT id+1 FROM table WHERE CLAUSE // pointing to the least available value
// or x = id +1 (after SELECT)
INSERT INTO table (id, ....) VALUES ('x', ....)
最佳答案
如果该列只是一个代理键而不用于其他目的(显示排序等),那么我只会使用您的数据库的AUTOINCREMENT等效项,并忽略ID中存在间隙的事实,因为有一点是独特而非服务于其他目的.备受推荐的“SQL反模式”一书中有一章题为“假性整齐”.这取决于你在建模什么以及当然如果数字确实带有超出标识符的含义,那么这一点就无关紧要了.

你想要阅读的一般概念(值得一点背景阅读,因为这些问题出现在所有地方,所以知道如何发现它们并有效地处理它们或设计它们是非常有用的)是差距和岛屿.有许多关于此的在线参考(this is the first one a quick search found,它是在讨论MSSQL,但概念是可转移的).

除了WHERE NOT EXISTS方法(通常建议作为代码读取的方式使您的意图更明显),您还可以执行以下操作:

SELECT TOP 1 t1.id-1
FROM     yourtable t1
LEFT OUTER JOIN 
         yourtable t2 
ON       t2.id=t1.id-1 -- will match if there is a row with the next ID down from the row in t1
WHERE    t2.id IS NULL -- the next ID down not found
AND      t1.id > 0     -- assume 1 is the lowest valid ID
ORDER BY t1.id

(这是MSSQL语法,你可能需要调整它)
这两种变体应该生成类似的查询计划,所以执行相同的操作,但我已经看到上述方法作为更复杂的查询的一部分表现更好,因此在您的情况下尝试两者并且验证哪种表现最佳是值得的.

此外,如果表为空,则当前呈现的方法都不会返回第一个ID:您将不会返回任何行(如果您将此作为子查询使用,则为NULL).解决这个问题的一种方法是使用id = 0的“无效”行,但这很脏(最终必须从许多其他查询中过滤掉),因此在逻辑中处理nothing / NULL而不是强力推荐.对于在生产中永远不会为空的表(例如,用户表,即使在初始安装时,初始设置/管理员用户也会有一条记录)这个或课程不是问题.

编辑:更正了查询以返回第一个ID(如果未找到),因为ypercube注意到第一个版本不会

转载注明原文:mysql – 如何按行顺序获取缺失值? - 代码日志