2010-10-06 3 views
8

Dans TableA, j'ai une colonne int.SQL: Sélectionnez la valeur la plus basse qui n'existe pas déjà

Est-il possible d'utiliser uniquement une instruction select pour sélectionner la valeur minimale dans la colonne EXISTANT et supérieure à 0?

Par exemple, si le col a les valeurs 1,2,9 l'instruction select retournera 3. Si le col a 9,10,11 il retournera 1.

Je peux y parvenir en utilisant un temp table ou en utilisant une boucle, mais je me demande si je peux le faire en utilisant juste une déclaration select?

Merci.

+0

Pourquoi avez-vous besoin de cela? Si vous souhaitez réutiliser les ID, c'est normalement une mauvaise idée. – Amadan

Répondre

2
select 
min(nt.id) 
from numbertable nt 
left outer join originaldata od 
on nt.id=od.id 
where od.id is null 

ont une table de nombre qui va de 1 à votre valeur maximale (ou supérieure)

1
SELECT DISTINCT x + 1 "val" 
EXCEPT SELECT DISTINCT x "val" 
ORDER BY "val" ASC 
LIMIT 1 

Que pensez-vous de cela?

+1

+1 de moi pour l'idée; trois notes - DISTINCT ne semble pas nécessaire et vous devriez avoir mis les clauses FROM. De plus, cela ne fonctionnera pas pour le second exemple (vous devrez peut-être unir la première partie avec SELECT 1). – Unreason

+0

True. Ce n'était qu'un point de départ. – Benoit

+0

Cela retournera la première valeur libre qui est une de plus qu'une valeur existante. Donc ça ne résout pas mes 2 exemples malheureusement et je ne vois pas comment je peux le changer donc ça le fait – Bob

0

essayez ceci: (Mise à jour)

declare @dummy varchar(10) ; 

set @dummy =(select top(1) id from dbo.b) 

if( @dummy= '1') 
begin 
select top(1)l.id + 1 as start 
from dbo.b as l 
    left outer join dbo.b as r on l.id + 1 = r.id 
where r.id is null 
end 
else 
begin 
select '1' 
end 
+0

Cela retournera la première valeur libre qui est une de plus qu'une valeur existante. Donc, il ne résout pas mes 2 exemples malheureusement – Bob

+0

j'ai mis à jour la réponse. J'espère que cela fonctionnera – anishMarokey

1
SELECT MIN(t1.ID+1) as 'MinID' 
FROM table t1 LEFT JOIN table t2 
On t1.ID+1=t2.ID 
Where t2.OtherField IS NULL 
0

pour cette solution:

declare @TestTable table (
    col int 
) 

/* Test Case 1: 1,2,9 */ 
insert into @TestTable 
    (col) 
    select 1 union all select 2 union all select 9 

SELECT MinValue = (SELECT ISNULL(MAX(t2.col),0)+1 
         FROM @TestTable t2 
        WHERE t2.col < t1.col) 
FROM @TestTable t1 
WHERE t1.col - 1 NOT IN (SELECT col FROM @TestTable) 
    AND t1.col - 1 > 0 

delete from @TestTable 

/* Test Case 2: 9,10,11 */ 
insert into @TestTable 
    (col) 
    select 9 union all select 10 union all select 11 

SELECT MinValue = (SELECT ISNULL(MAX(t2.col),0)+1 
         FROM @TestTable t2 
        WHERE t2.col < t1.col) 
FROM @TestTable t1 
WHERE t1.col - 1 NOT IN (SELECT col FROM @TestTable) 
    AND t1.col - 1 > 0 
1
select min(id) from (select 1 id from TableA where 1 not in (select id from TableA) UNION select id + 1 id from TableA where id + 1 not in (select id from TableA)) as min_ids; 
0

Je dupliqués ma réponse de here:

SELECT MIN(a.id) + 1 AS firstfree 
FROM (SELECT id FROM table UNION SELECT 0) a 
LEFT JOIN table b ON b.id = a.id + 1 
WHERE b.id IS NULL 

Cela gère tous les cas, je peux penser - y compris pas les enregistrements existants du tout.

La seule chose que je n'aime pas cette solution est que les conditions supplémentaires doivent être inclus deux fois, comme ça:

SELECT MIN(a.id) + 1 AS firstfree 
FROM (SELECT id FROM table WHERE column = 4711 UNION SELECT 0) a 
LEFT JOIN table b ON b.column = 4711 AND b.id = a.id + 1 
WHERE b.id IS NULL 

S'il vous plaît noter également les commentaires sur le verrouillage et la concurrence - l'obligation de combler les lacunes est dans la plupart des cas une mauvaise conception et peut causer des problèmes. Cependant, j'avais une bonne raison de le faire: les identifiants doivent être imprimés et dactylographiés par des humains et nous ne voulons pas avoir d'ID avec beaucoup de chiffres après un certain temps, alors que tous les bas sont gratuits ...

Questions connexes