如何在包含连续int值的列中获得第一个间隙

时间:2012-07-17 09:27:18

标签: sql sql-server sql-server-2008-r2

我在SQL Server数据库表中有一个列,有一个包含整数值的列,我希望得到最大值,除非系列中有间隙,然后我想获得第一个缺失值。

例如,从下表中,我希望获得价值4

1
2
null
3

上面很简单,但是如果表中包含如下数据,我怎样才能找到我缺少的id,在这种情况下它将是8

1
3
2
4
null
5
7
6
null
10
9

//////////////////

编辑:

我最初实现了@ podiluska的答案并且接受了它然而当我用超过10K行的表进行测试时它非常慢,所以我采取了@vmvadivel的答案并稍微改变它,如下所示,它工作得非常快,但仍然不是我想要的100%:

SELECT Number
FROM 
(
    SELECT ROW_NUMBER() OVER(ORDER BY iValue) AS Number
    FROM tblNumbers WHERE iValue IS NOT NULL
) temp
WHERE Number NOT IN 
(
    SELECT iValue FROM tblNumbers WHERE iValue IS NOT NULL
)

这很有效,但是如果所有iValue字段都为null,那么我什么都没有回来,但我希望它返回1,因为它将是系列中的第一个值,显然我可以处理这个在C#代码中,但我确信如果上面的查询没有返回一行,必须有一种方法返回1?

我已使用Select Number更改了顶级SELECT Coalesce(Number, 1),但它没有用,有任何想法如何解决这个问题?

由于

3 个答案:

答案 0 :(得分:5)

如果#t是你的表

select min(t1.number)+1 
from #t t1
left join #t t2 
           on t1.number = t2.number-1
where t2.number is null

答案 1 :(得分:1)

SELECT
    t1.number + 1 AS range_start,
    MIN(t2.number) - 1 AS range_end
FROM test t1
INNER JOIN test t2
    ON t2.number > t1.number
WHERE t1.number IS NOT NULL
GROUP BY t1.number
HAVING t1.number + 1 <= MIN(t2.number) - 1

如果向表中添加数字15,输出将为:

range_start  range_end
          8          8
         11         14

它找到每对连续的数字,间隙至少为1。然后,它会从中添加或减去一个,以便start_rangeend_range是差距的范围。

答案 2 :(得分:1)

如果你有一个数字表,其中包含连续的int值,那么你可以这样做:

SELECT * FROM 
(
    SELECT ROW_NUMBER() OVER(ORDER BY iValue) AS Number FROM tblNumbers
) temp
WHERE Number NOT IN 
(
    SELECT [ID] FROM tblFindGaps
)
GO