Sql 从列值中查找缺少的键ID或数字

Sql 从列值中查找缺少的键ID或数字,sql,sql-server,database,sql-server-2014,Sql,Sql Server,Database,Sql Server 2014,需要查找已删除的缺失编号或尚未删除的列 例如: 我有一个名为Person的表,其中有列[PersonID][PersonName] [PersonID]是主要的递增数字,例如从1到N PersonID PersonName 1001 ABC 1002 ABC 1003 XYZ 1004 MNO 100

需要查找已删除的缺失编号或尚未删除的列

例如:

我有一个名为Person的表,其中有列[PersonID][PersonName]

[PersonID]是主要的递增数字,例如从1到N

PersonID            PersonName
1001                       ABC
1002                       ABC
1003                       XYZ
1004                       MNO
1006                       ABC
1008                       MNO
1009                       ABC
1010                       ABC
1011                       XYZ
1014                       ABC
1015                       ABC
1016                       XYZ
1017                       MNO
在给定的表中,PersonID like列中缺少一些数字

1005
1007
1012 
1013
只需要找到丢失的号码

注意:我的表中有超过2000万条记录。
因此,请建议一种更快的方法来找到所需的数字。

最简单的方法是获取范围。您可以使用lead执行此操作:

如果仍然需要ID列表,可以扩展范围,但这取决于数据库

在SQL Server 2008中,这对性能要求更高,但您可以做到:

select personid + 1, tnext.personid - 1 as end_range,
       text.personid - personid - 1 as num_missing
from t cross apply
     (select top (1) t2.person_id
      from t t2
      where t2.personid > t.person_id
      order by t2.personid asc
     ) tnext
where tnext.personid <> personid + 1;

创建另一个表并填充PersonID的最小和最大范围之间的所有数字。执行左/右反联接以获取缺少的数字列表

select * from NewIDTable a
left join OriginalTable b  on a.PersonID=b.PersonID
where b.Personid is null

感谢大家的支持和分享。我已经找到了使用ROWNUMBER查找缺少的行的方法


我删除了不兼容的数据库标记。请仅使用您真正使用的数据库进行标记。创建一个包含所有预期数字的表,然后反连接到此表以查找差距。根据您的示例数据,您不应该期望1005,而不是5吗?另外,如果您没有并发ID,为什么这很重要?它们不需要编辑。需要重新生成数字。PersonID是您的主键吗?它是群集的吗?如果以上任一问题的答案为“是”,则重新生成数字是一个坏主意。“lead”不是公认的内置函数名。这就是为什么了解您使用的RDBMS很重要的原因@Shahbazaeded38i正在使用MSSQL2014@Shahbazsaeed38 . . . 铅在最初标记为问题的两个数据库中都可用。它于2012年被添加到SQL Server中。但2008年即将完全失去对@Shahbazaede38的所有支持。这本身就是一个原因。正如我在问题中提到的,表中有2000多条记录,每次我需要找出差异时创建表并不是一个好方法……表每分钟都在增加。
select * from NewIDTable a
left join OriginalTable b  on a.PersonID=b.PersonID
where b.Personid is null
 SELECT
 NOTEXIST  FROM  ( 
 SELECT  ROW_NUMBER() OVER (ORDER BY PERSONID) NOTEXIST ,PERSONID  FROM  #A )  T
 WHERE NOTEXIST NOT IN  ( SELECT PERSONID  FROM  PERSONID )