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

Posted

技术标签:

【中文标题】从列值中查找缺失的键 ID 或数字【英文标题】:Find the Missing Key ID or Numbers from a Column values 【发布时间】:2019-04-04 10:48:09 【问题描述】:

需要查找缺失的号码,已删除或某列还没有。

例如:

我有一个名为 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 中有一些缺失的数字,例如

1005
1007
1012 
1013

只需要找到丢失的数字。

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

【问题讨论】:

我删除了不兼容的数据库标签。请仅使用您真正使用的数据库进行标记。 创建一个包含所有预期数字的表,然后反连接到该表以查找差距。 根据您的样本数据,您不应该期待1005,而不是5吗?另外,如果您没有并发 ID,为什么这很重要?他们不需要。 @Larnu 问题已编辑。需要重新生成数字。 PersonID 是您的主键吗?是CLUSTERED吗?如果其中任何一个问题的答案是“是”,那么重新生成数字是一个的想法。 【参考方案1】:

感谢所有支持并分享一些观点的人。我找到了使用 ROWNUMBER() 查找 Missing 的方法。

 SELECT
 NOTEXIST  FROM  ( 
 SELECT  ROW_NUMBER() OVER (ORDER BY PERSONID) NOTEXIST ,PERSONID  FROM  #A )  T
 WHERE NOTEXIST NOT IN  ( SELECT PERSONID  FROM  PERSONID )

【讨论】:

【参考方案2】:

创建另一个表并填充 PersonID 的 Min 和 Max 范围之间的所有数字。进行反连接(左/右)以获取丢失的数字列表。

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

【讨论】:

正如我在问题中提到的,表中有 20M + 记录,每次我需要查找差异时创建表并不是一个好方法......表每分钟都在增加。跨度> 【参考方案3】:

最简单的方法是获取范围。你可以通过lead() 做到这一点:

select personid + 1, next_personid - 1 as end_range,
       next_personid - personid - 1 as num_missing
from (select t.*,
             lead(personid) over (order by personid) as next_personid
      from t
     ) t
where next_personid <> personid + 1;

如果您仍然想要 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;

【讨论】:

'lead' 不是可识别的内置函数名称。 这就是为什么知道你正在使用什么 RDBMS 很重要@Shahbazsaeed38 我正在使用 MSSQL 2014 @Shahbazsaeed38 。 . . lead() 在最初标记在问题上的两个数据库中都可用。它于 2012 年被添加到 SQL Server (docs.microsoft.com/en-us/sql/t-sql/functions/…)。 但是 2008 年即将完全失去所有支持 @Shahbazsaeed38。这本身就是一个原因。

以上是关于从列值中查找缺失的键 ID 或数字的主要内容,如果未能解决你的问题,请参考以下文章

使用SQL查找多列行中的最小值

从列中查找最大值并选择它们的行

sql查找最小缺失值与重用被删除的键(转载)

在 SQL 中查找表之间缺失的数字

使用正则表达式删除Mysql中列值中的括号()

从序列中为配置单元中的每个值查找缺失的数字