如何使用SQL查找序列字段中缺少的数字?

如何使用SQL查找序列字段中缺少的数字?,sql,sql-server,tsql,stored-procedures,Sql,Sql Server,Tsql,Stored Procedures,我有一个名为Student的表和名为StudentNumber的字段名 学生桌 期望输出 我试着像下面一样 Declare @trans int; set @trans = 1; while(@trans <=50000) BEGIN if((select StudentNumber from [Student] where StudentNumber = @trans) != @trans) BEGIN print @trans; END END

我有一个名为Student的表和名为StudentNumber的字段名

学生桌

期望输出

我试着像下面一样

Declare @trans int;
set @trans = 1;

while(@trans <=50000)
BEGIN
    if((select StudentNumber from [Student] where StudentNumber = @trans) != @trans)
    BEGIN
        print @trans;
    END
END

set @trans = @trans + 1;
Declare @trans int;
set @trans = 1;

while(@trans <=50000)
BEGIN
if NOT EXISTS (select StudentNumber from [Student] where StudentNumber = @trans)
BEGIN
    print @trans;
END
END

set @trans = @trans + 1;
像这样尝试

declare @id int
declare @maxStudentNumber int

set @id = 1
select @maxStudentNumber = max(StudentNumber) from Student

create table #MissingIds
(
    id int
)

while @id < @maxStudentNumber
begin
    insert into #MissingIds values(@id)
    set @id = @id + 1
end

select m.id 
from #MissingIds m 
left join Student s 
on m.id = s.StudentNumber 
where s.StudentNumber is null

drop table #MissingIds

您可以使用SQL Server 2016及更高版本:

SELECT Number
FROM (select cast([key] as int) + 
      (SELECT MIN(StudentNumber) FROM Students) as number 
      from OPENJSON( '[1' 
      + replicate(',1',(SELECT MAX(StudentNumber) FROM Students)-
                       (SELECT MIN(StudentNumber) FROM Students))+']')) n
LEFT JOIN Students s
  ON n.number = s.StudentNumber
WHERE s.StudentNumber IS NULL;
注意:您可以与任何其他理货编号生成器交换第一个子查询。
更多信息:

应该如下所示

Declare @trans int;
set @trans = 1;

while(@trans <=50000)
BEGIN
    if((select StudentNumber from [Student] where StudentNumber = @trans) != @trans)
    BEGIN
        print @trans;
    END
END

set @trans = @trans + 1;
Declare @trans int;
set @trans = 1;

while(@trans <=50000)
BEGIN
if NOT EXISTS (select StudentNumber from [Student] where StudentNumber = @trans)
BEGIN
    print @trans;
END
END

set @trans = @trans + 1;

您可以执行以下操作

;with report as(
   select 1 as missing
   union all
   select missing + 1
   from report
   where missing < @max
)


select *
from report m
where not exists ( select 1 from student s where s.id = m.missing)
option (maxrecursion 0);

希望这能帮助你

我知道你只是为了运动而尝试解决它 如何使用递归CTE实现同样的功能

with missingstudents (StudentNumber)
as (
  select StudentNumber-1 from Students s 
     where not exists (
       select StudentNumber from Students s2 
          where s.StudentNumber-1 = s2.StudentNumber)
UNION ALL
  select StudentNumber-1 from missingstudents s 
     where not exists (
       select StudentNumber from Students s2 
          where s.StudentNumber-1 = s2.StudentNumber)
)
select * from missingstudents
您可以尝试以下方法:

select m.number from 
(select min(StudentNumber) a,max(StudentNumber) b from Students) c ,master..spt_values M
where c.a <= m.number
and c.b > = m.number
and type ='P'
and m.number not in (select StudentNumber from Students)

到目前为止你试过什么?@jhen我试过像上面一样循环直到maxnumber,并在每次迭代中检查id是否存在?50000这个数字一直是固定的吗?或者可能会被更改?@monah我正在寻找少于50000的缺失数字。它不会为空。没有number@Liamneesan在左联接的情况下,如果右表中没有匹配的行,那么右表中的所有列都将返回空值。明白你的确切意思吗?它将不为空?
select m.number from 
(select min(StudentNumber) a,max(StudentNumber) b from Students) c ,master..spt_values M
where c.a <= m.number
and c.b > = m.number
and type ='P'
and m.number not in (select StudentNumber from Students)