假设您有一个T(A)
只允许正整数的表,例如:
1,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,结果是10
.我们总是可以使用ORDER BY
和DISTINCT
排序和删除重复项.但是,要找到不在列表中的最小整数,我想出了以下SQL
查询:
select list.x + 1
from (select x from (select distinct a as x from T order by a)) as list, T
where list.x + 1 not in T limit 1;
Run Code Online (Sandbox Code Playgroud)
我的想法是启动a counter
和1,检查该计数器是否在list
:如果是,则返回,否则递增并再次查看.但是,我必须将该计数器作为1启动,然后递增.该查询适用于大多数情况,因为有一些极端情况,如1
.我怎样才能实现这个目标,SQL
或者我应该采用完全不同的方向来解决这个问题?
因为SQL在集合上工作,所以中间SELECT DISTINCT a AS x FROM t ORDER BY a
是冗余的.
在整数列中查找间隙的基本技术是查找当前条目加1不存在的位置.这需要某种自联接.
您的查询并不遥远,但我认为它可以简化为:
SELECT MIN(a) + 1
FROM t
WHERE a + 1 NOT IN (SELECT a FROM t)
Run Code Online (Sandbox Code Playgroud)
NOT IN充当一种自我联接.这不会产生任何空表,但应该没问题.
select min(y.a) as a
from
t x
right join
(
select a + 1 as a from t
union
select 1
) y on y.a = x.a
where x.a is null
Run Code Online (Sandbox Code Playgroud)
即使在空表中它也能工作
您可以执行以下操作,尽管您可能还想定义一个范围 - 在这种情况下您可能需要几个 UNION
SELECT x.id+1
FROM my_table x
LEFT
JOIN my_table y
ON x.id+1 = y.id
WHERE y.id IS NULL
ORDER
BY x.id LIMIT 1;
Run Code Online (Sandbox Code Playgroud)