从数据库表获取空值

时间:2019-03-25 12:33:15

标签: c# sql-server

我有一个数据库表,该表的列的值在1到999之间 但是它有一些空间,例如1,2,3,4,5,6,11,15等...

从该表中获取“下一个号码”最好是什么?

预先感谢您的帮助

3 个答案:

答案 0 :(得分:2)

执行此操作的一种方法是获取每一行的前一行,然后检查要执行的步骤。
这将不能很好地执行,并且当有1个以上的用户正在添加新行时,这不是安全的!

declare @t table (number int)
insert into @t values (1), (2), (3), (4), (5), (6), (11), (12)

select top 1 
       (select top 1 t2.number + 1 from @t t2 where t2.number < t.number order by t2.number desc) as prior  
from   @t t
where  number <> (select top 1 t2.number + 1 from @t t2 where t2.number < t.number order by t2.number desc)
order by t.number

结果将是7

这是另一个选择

select top 1
       t.number + 1 
from   @t t
  left join @t t2 on t.number = t2.number - 1
where  t2.number is null
order by t.number

此方法甚至可能比Robin的解决方案更快

编辑
正如丹尼尔(Daniel)在评论中指出的那样,如果空白恰好是第一行,则它将永远不会返回1
要解决此问题,我们可以为缺少的第一行检索一个值,并通过使用并集将其添加到我们的结果中。

select top 1 number 
from   ( select top 1
                t.number + 1 as number
         from   @t t
           left join @t t2 on t.number = t2.number - 1
         where  t2.number is null

         union

         select 1 as number
         from   @t t
         where not exists (select 1 from @t t3 where t3.number = 1)
       ) t 
order by t.number

由于额外的查询只能按索引检索确切的一行,因此不会对性能产生太大影响

答案 1 :(得分:1)

您可以使用CTE生成数字,然后获取与记录不匹配的第一个数字。...

如您所言,它不是一张大桌子,效果很好

  

我有一个数据表,其中的列的值在1到999之间

关于其他答案,两个答案都比大型表的答案要快得多,但是如果您的输入从2或更大开始,则没有一个答案会返回正确的值(1)。

我不知道此请求的目的,但是请注意,以这种方式计算值的两个用户同时工作可以得到相同的值。如果您想将此值用作主键或唯一索引的一部分

;with numbers as (
    SELECT 1 as nrstart, MAX(yourcolumn) as nrend FROM yourTable
    UNION ALL
    SELECT nrstart+1, nrend FROM numbers
    WHERE nrstart <= nrend
)
SELECT TOP 1 nrstart
FROM numbers 
WHERE NOT EXISTS (SELECT 1 FROM yourTable WHERE yourcolumn = numbers.nrstart)
ORDER BY nrStart
OPTION (MAXRECURSION 0); 

答案 2 :(得分:0)

您需要第一个数字,该数字加一个不在表中。

SELECT TOP 1 (Number + 1) FROM myTable a WHERE NOT EXISTS 
    (SELECT * FROM myTable b WHERE b.Number = a.Number + 1) 
ORDER By Number

正如各种评论中所提到的那样,如果第二位用户在寻找缺口的同时存在第二位用户填补缺口的风险,则应在事务中完成这种事情。