2010-10-06 82 views
8

在TableA中,我有一個int列。SQL:選擇不存在的最低值

是否有可能只使用select語句來選擇不存在且大於0的列中的最小值?

例如,如果山坳有值1,2,9 select語句將返回3. 如果山坳有9,10,11它將返回1.

我可以在此使用取得臨時表或使用循環,但我想知道如果我可以使用只是一個選擇語句?

謝謝。

+0

你爲什麼需要這個?如果你想重用ID,通常是一個糟糕的想法。 – Amadan 2010-10-06 11:36:59

回答

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

有從1到你的最大價值數表(或更高版本)

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

這是怎麼回事?

+1

從我這裏得到+1的想法;三個註釋 - DISTINCT似乎不是必需的,您應該已經放置了FROM子句。另外,它不適用於第二個示例(您可能必須將第一個部分與SELECT 1結合)。 – Unreason 2010-10-06 11:50:46

+0

是的。這僅僅是一個起點。 – Benoit 2010-10-06 11:51:35

+0

這將返回比現有值多一個的第一個空閒值。所以它不能解決我的兩個例子,不幸的是,我看不到我怎麼能改變它,所以它不會 – Bob 2010-10-06 12:00:49

0

試試這個:(更新)

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

這將返回比現有值多一個的第一個空閒值。所以它不能解決我的2個例子不幸的是 – Bob 2010-10-06 12:01:08

+0

我更新了答案.hope它會工作 – anishMarokey 2010-10-06 14:52:31

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

試試這個:

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

我重複我的回答從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 

這個處理我能想到的所有情況 - 包括沒有任何現有的記錄。

我不喜歡這個解決方案的唯一的事情就是附加條件必須包含兩次,這樣的:

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 

也請注意有關鎖定和併發性的評論 - 要求以填補空白在大多數情況下,設計不好並可能導致問題。然而,我有一個很好的理由這樣做:身份證將被打印並由人類輸入,我們不想在一段時間後擁有多位數的身份證,而所有的低位身份證都是免費的...