从列值中查找缺失的键 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 或数字的主要内容,如果未能解决你的问题,请参考以下文章