2011-12-29 125 views
3

我如何才能找到的值中的最低值未填寫或不存在T-SQL找到最小值

例如

001 
002 
003 
013 
015 

結果必須返回004

選擇min

回答

1

假設你在表中的序列YourNumbersTable 試試這個(SQL Server 2005+):

declare @min int, @max int 
select @min = MIN(Id), @max = MAX(Id) from YourNumbersTable 

;WITH numbers(id) as 
(
    SELECT @min id 
    UNION ALL 
    SELECT id+1 
    FROM numbers 
    WHERE id <= @max 
) 

SELECT MIN(Numbers.id) 
FROM Numbers 
    LEFT JOIN YourNumbersTable ON Numbers.Id = YourNumbersTable.Id 
WHERE YourNumbersTable.Id IS NULL 
OPTION(MAXRECURSION 0) 
3
declare @T table(Number int) 

insert into @T values (1),(2),(3),(13),(15) 

select top 1 Number + 1 
from @T 
where Number + 1 not in (select Number from @T) 
order by Number 

更新:

使用炭(3)零填充一個版本。

declare @T table(ID char(3)) 

insert into @T values ('001'),('002'),('003'),('013'),('015') 

select top 1 right(1001 + Id, 3) 
from @T 
where Id + 1 not in (select Id from @T) 
order by Id 
+0

這通常工作得很好,但如果'009'被存儲爲'CHAR(3)',這將如何工作?問題中的前導零使我認爲它是一個「CHAR」而不是「INT」字段。只是想知道:) – Seph 2011-12-29 08:15:02

+0

@Seph - 添加了一個char(3)作爲數據類型的版本。除了結果值以及存在大量隱式類型轉換並且不會在'Number'上使用任何索引的事實之外,沒有什麼區別。 – 2011-12-29 08:19:59

0

也許我有一個替代解決方案。由於其中的循環,它可能在較寬的數字範圍內變慢。

-- prepare a table to have your example 
declare @ref table (id int) 
insert into @ref (id) values (1), (2), (3), (13), (15) 

-- this will return 1 
select min(id) from @ref 

-- magic happens here 
declare @i int, @max int, @returnValue int 
select @i = min(id), @max = max(id) from @ref 
declare @tmp table (id int) 
while @i <= @max 
    begin 
    insert into @tmp (id) values (@i) 
    set @i = @i + 1 
    end 

select @returnValue = min(t.id) 
    from @tmp t left outer join @ref r on t.id = r.id 
    where r.id is null 

-- this will return 4 
select @returnValue 
1

試試這個(無連接,無REC-CTE)

declare @T table(n int) 

insert into @T values (1),(2),(3),(13),(15) 


select max(n)+1 from (
    select *,l=n-row_number() over(order by n) 
    from (
     select n from @T 
     union 
     select 0 -- what about 0 ?? 
    ) as s 
) as a 
where l=-1 
1

這類似於what @szauri has suggested,但沒有聚集:

; 
WITH ranked AS (
    SELECT n, r = ROW_NUMBER() OVER (ORDER BY n) 
    FROM @T 
) 
SELECT TOP 1 r 
FROM ranked 
WHERE n <> r 
ORDER BY n 

提示:這兩種@ szauri和我的解決方案需要SQL Server 2005或更高版本。