2011-12-29 79 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或更高版本。