如何使用sql server在表中查找缺失的数字?

时间:2014-09-24 10:03:17

标签: sql sql-server

我想在表格中找到丢失的数字。表格就像这样。

   Sno                Branch 

    1                   ABC
    2                   ABC
    3                   ABC
    5                   ABC   // 4th sno is missing
    6                   ABC
    8                   ABC   // 7th sno is missing
   10                   ABC   // 9th sno is missing 

我使用此查询找到了丢失的SNo

 ALTER proc [dbo].[K_RT_DCNoMissing]--1,50 
 as
 begin

 declare @id int
  set @id = 0
 declare @maxid int

 --set @id = @fromvalue
 select @maxid = (select count(*) dcno  from K_RT_Dailyentryretail nolock)   


create table #IDSeq
(
id int 
)

 while 0<@maxid--whatever you max is
 begin
insert into #IDSeq values(@id)

set @id = @id + 1
set @maxid = @maxid - 1
-- print @maxid
end

select 
s.id  
from 
#idseq s 
left join K_RT_Dailyentryretail t on 
    s.id = t.dcno 

  where t.dcno is  null  order by s.id asc

  drop table #IDSeq

  end

我这样出去......

  MissingNo's
    4
    7
    9

现在我想要显示Sno,其分支名称为。

    MissingNo's           Branch
      4                   ABC
      7                   ABC
      9                   ABC

我如何获得分支名称......

Am getting output as
4    abc
4    cde
4    fgh
7    abc
7    cde
7    fgh

but what actually am expecting is
4    abc
7    cde
.     ..
.     ..

3 个答案:

答案 0 :(得分:2)

您可以使用CTE构建所有分支的表格以及每个分支的完整数字范围。然后将其连接到主表以查找缺少的内容。这将允许您获得连续丢失的数字,例如缺少3,4和5。您可以将@minid@maxid调整为您想要的范围。如果@maxid可能大于32767,那么您将需要对批量范围执行某些操作。

declare @minid int, @maxid int

set @minid = 1
set @maxid = (select count(*) dcno from K_RT_Dailyentryretail with (nolock))

; with Branches as (
    select distinct Branch from K_RT_Dailyentryretail
)
, CTE as
(
    select @minid as Sno, Branch from Branches
    union all
    select Sno + 1, Branch from CTE where Sno < @maxid
)

select  CTE.Sno, CTE.Branch from CTE
    left outer join K_RT_Dailyentryretail k on k.Branch = CTE.Branch and CTE.Sno = k.Sno
where k.Sno is null
option (MAXRECURSION 32767);

SQLFiddle:http://sqlfiddle.com/#!3/13653/13

答案 1 :(得分:0)

我在考虑您之间的GAP总是只有1位数。 在这种情况下,以下将适合您,

;With CTE as
(
select Sno,Branch,ROW_NUMBER() over (order by Sno) R
 from C
)
select a.Sno+  1,a.Branch from CTE as a
left join CTE as b on a.R + 1= b.R 
where a.Sno + 1 <> b.Sno

还有一件事是,对于想要分支的缺失行,我认为对于缺失的行,您希望拥有前一行的分支。

答案 2 :(得分:0)

假设每个分支都拥有它自己的一组sno数字,这就有效:

select sno-1 as sno, branch
from t1
where sno-1 NOT in (select sno from t1 as t2 where t1.branch = t2.branch)
and sno > 1
;

您可以在此处查看:http://sqlfiddle.com/#!3/daa81d/3

如果sno是一个唯一的密钥,请告诉我,我会修改答案。

编辑:就像AK47的回答一样,我假设差距只有一行。