-1

I have a table called Student and field name called StudentNumber

Student Table

StudentNumber
-------------
 1
 2 
 3
 4
 5
 8
 10

Expecting output

6
7
9

I tried like below

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;
Lukasz Szozda
  • 139,860
  • 19
  • 198
  • 228
Liam neesan
  • 1,949
  • 4
  • 27
  • 56

6 Answers6

0

Try like this;

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
paparazzo
  • 43,659
  • 20
  • 99
  • 164
lucky
  • 12,110
  • 4
  • 20
  • 41
  • It will not be null. there is no number – Liam neesan Nov 25 '17 at 09:22
  • @Liamneesan In the case of a `LEFT JOIN`, if there is no matching row in the right-hand table, you get a `NULL` value back for all columns from the right-hand table. See https://stackoverflow.com/questions/38549/what-is-the-difference-between-inner-join-and-outer-join – Matt Gibson Nov 25 '17 at 09:26
  • What do you mean exactly "It will not be null" ? – lucky Nov 25 '17 at 09:28
0

You could use (SQL Server 2016 and above):

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;

DBFiddle Demo

Note: You could exchange first subquery with any other tally number generator. More info: SQL, Auxiliary table of numbers

Lukasz Szozda
  • 139,860
  • 19
  • 198
  • 228
0

it should be like below

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

You can do the following

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

Here a working demo

Result

  missing
    6
    7
    9

Hope that this will help you

Monah
  • 6,462
  • 6
  • 20
  • 51
0

I know you try to solve it iterative, just for sports an idea how to achieve the same using recursive 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
aschoerk
  • 2,913
  • 2
  • 14
  • 28
0

You can try this:

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)
Anagha
  • 908
  • 1
  • 8
  • 17