2012-07-17 68 views
0

我在SQL Server数据库表中有一列,有一列包含整数值,我想获得最大值,除非系列中存在差距,那么我想获得第一个缺失的值。如何获得包含顺序int值的列中的第一个空位

例如从下面的表,我希望得到价值4

1 
2 
null 
3 

以上是简单的,但如果表中包含类似下面的数据,我怎么能找到我缺少其中的ID,这种情况下,这将是8

1 
3 
2 
4 
null 
5 
7 
6 
null 
10 
9 

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

编辑:

I最初实现了@ 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字段为空,然后我没有得到任何东西,但我想它返回1,因为这将是第一个值在系列中,显然我可以在C#代码中处理这个问题,但是如果上面的查询没有返回一行,我相信必须有返回1的方法吗?

我已经改变了顶级Select NumberSELECT Coalesce(Number, 1)但它没有工作,任何想法如何解决这个问题?

感谢

+0

什么版本的SQL Server? – 2012-07-17 09:35:47

+0

SQL Server 2008 R2 – 03Usr 2012-07-17 09:37:37

+0

您似乎在两个地方都使用了tblNumbers。在WHERE子句中,将其更改为具有您在问题中显示的数据的实际表格。 tblNumbers应该有1到n个连续的运行号码。 – vmvadivel 2012-07-18 02:47:51

回答

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
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 

它发现每次连续一对数字,至少有一个差距。然后它加上或减去一个,这样start_rangeend_range是差距的范围。

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 
+0

谢谢,即使这不是很正确,我认为这是一个更好的解决方案,因为如果我们在表格中有很多行,它比@ podiluska的答案更快。这并没有处理这样一个事实,即我们可以有多行,其中包含空值。我会解决这个问题,并在下面发表我自己的回答。 – 03Usr 2012-07-17 15:56:26

相关问题