我有一个带有整数ID列的表.我想获得此列的最小未使用值.查询应找到表ID中的第一个孔并获取其中的最小值.我将尝试用一些例子来解释它.
例1:无孔表
在这种情况下,我有一个没有孔的表,查询应该只是得到最小的未使用值:应该得到:4
|id|
|1 |
|2 |
|3 |
Run Code Online (Sandbox Code Playgroud)
示例2:顶部有孔的桌子
在这种情况下,我们在顶部有一个洞(缺失值:1).查询找到漏洞并获取其中的最小值:应该得到1.
|id|
|2 |
|3 |
|4 |
Run Code Online (Sandbox Code Playgroud)
同样在这种情况下,我们在顶部有一个洞,但我们内部有更多的缺失值(缺少值:1和2).查询找到漏洞并获取其中的最小值:应该得到1.
|id|
|3 |
|4 |
|5 |
Run Code Online (Sandbox Code Playgroud)
例3:中间有孔的桌子
在这种情况下,我们在中间有一个洞(缺少值:2和3).查询找到漏洞并获取其中的最小值:应该得到2.
|id|
|1 |
|4 |
|5 |
Run Code Online (Sandbox Code Playgroud)
例4:在顶部和中间有孔的桌子
在这种情况下,我们有多个洞:一个在顶部(缺失值:1),一个在中间(缺失值:3).查询找到第一个洞并获得其中的最小值:应该得到1.
|id|
|2 |
|4 |
|6 |
Run Code Online (Sandbox Code Playgroud)
我已经尝试过这篇文章中提出的解决方案,但在我的案例中它没有按预期工作.有任何想法吗?
SELECT min(unused) AS unused
FROM (
SELECT MIN(t1.id)+1 as unused
FROM yourTable AS t1
WHERE NOT EXISTS (SELECT * FROM yourTable AS t2 WHERE t2.id = t1.id+1)
UNION
-- Special case for missing the first row
SELECT 1
FROM DUAL
WHERE NOT EXISTS (SELECT * FROM yourTable WHERE id = 1)
) AS subquery
Run Code Online (Sandbox Code Playgroud)
使用连接而不是 EXISTS 的方式略有不同:-
SELECT MIN(t1.id)
FROM
(
SELECT 1 AS id
UNION ALL
SELECT id + 1
FROM yourTable
) t1
LEFT OUTER JOIN yourTable t2
ON t1.id = t2.id
WHERE t2.id IS NULL;
Run Code Online (Sandbox Code Playgroud)
使用子查询的任何解决方案的缺点是它们不太可能使用任何索引