Devolver el integer más bajo no en una list en SQL

Supone que tiene una tabla T(A) con solo integers positivos permitidos, como:

 1,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18 

En el ejemplo anterior, el resultado es 10 . Siempre podemos usar ORDER BY y DISTINCT para orderar y eliminar duplicates. Sin embargo, para encontrar el número integer más bajo que no figura en la list, se me ocurrió la siguiente consulta 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; 

Mi idea es iniciar un counter y 1, verificar si ese contador está en la list : si lo está, devolverlo; de lo contrario, boost y mirar nuevamente. Sin embargo, tengo que comenzar ese contador como 1, y luego incrementarlo. Esa consulta funciona en la mayoría de los casos, ya que hay algunos casos de esquina como en 1 . ¿Cómo puedo lograr eso en SQL o debo ir en una dirección completamente diferente para resolver este problema?

Como SQL funciona en sets, el intermedio SELECT DISTINCT a AS x FROM t ORDER BY a es networkingundante.

La técnica básica de search un espacio en una columna de numbers integers es encontrar donde no existe la input actual más 1. Esto requiere una auto unión de algún tipo.

Su consulta no está lejos, pero creo que se puede simplificar a:

 SELECT MIN(a) + 1 FROM t WHERE a + 1 NOT IN (SELECT a FROM t) 

El NOT IN actúa como una especie de auto-unión. Esto no producirá nada de una tabla vacía, pero debería estar bien de lo contrario.

SQL Fiddle

 select min(ya) as a from tx right join ( select a + 1 as a from t union select 1 ) y on ya = xa where xa is null 

Funcionará incluso en una table vacía

Puede hacer lo siguiente, aunque también quiera definir un range, en cuyo caso podría necesitar un par de UNIONs

 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; 

Siempre puede crear una tabla con todos los numbers del 1 al X y luego unir esa tabla con la tabla que está comparando. Luego solo encuentra el valor TOP en tu instrucción SELECT que no está presente en la tabla que estás comparando

 SELECT TOP 1 table_with_all_numbers.number, table_with_missing_numbers.number FROM table_with_all_numbers LEFT JOIN table_with_missing_numbers ON table_with_missing_numbers.number = table_with_all_numbers.number WHERE table_with_missing_numbers.number IS NULL ORDER BY table_with_all_numbers.number ASC; 

En SQLite 3.8.3 o posterior, puede usar una expresión de tabla común recursiva para crear un contador. Aquí, dejamos de contar cuando encontramos un valor que no está en la tabla:

 WITH RECURSIVE counter(c) AS ( SELECT 1 UNION ALL SELECT c + 1 FROM counter WHERE c IN t) SELECT max(c) FROM counter; 

(Esto funciona para una tabla vacía o falta 1 ).

Esta consulta clasifica (comenzando desde el range 1) cada número distinto en order ascendente y selecciona el range más bajo que es menor que su número. Si ningún range es menor que su número (es decir, no hay vacíos en la tabla), la consulta devuelve el número máximo +1.

 select coalesce(min(number),1) from ( select min(cnt) number from ( select number, (select count(*) from (select distinct number from numbers) b where b.number <= a.number) as cnt from (select distinct number from numbers) a ) t1 where number > cnt union select max(number) + 1 number from numbers ) t1 

http://sqlfiddle.com/#!7/720cc/3

Solo otro método, usando EXCEPTO esta vez:

 SELECT a + 1 AS missing FROM T EXCEPT SELECT a FROM T ORDER BY missing LIMIT 1; 
 SELECT min(ta) - 1 FROM t LEFT JOIN t t1 ON t1.a = ta - 1 WHERE t1.a IS NULL AND ta > 1; -- exclude 0 

Encuentra el número más pequeño mayor que 1, donde el siguiente número más pequeño no está en la misma tabla. Ese número faltante es devuelto.

Esto funciona incluso si falta 1. Hay varias respuestas que comtestingn en la dirección opuesta. Todos ellos fallarían con 1 faltante.

SQL Fiddle.