如何从参数开始并按顺序递增的表字段中查找缺失的数字?
假设我有一个 sql server 表:
NumberTaken CompanyName
2 ; 弗雷德
3 弗雷德
4 ;弗雷德
6 弗雷德< br> 7 弗雷德
8 弗雷德
11 ; Fred
我需要一种有效的方法来传递参数[ StartingNumber] 并从 [StartingNumber] 开始依次计数,直到找到丢失的数字。
例如,请注意表中缺少 1、5、9 和 10。
如果我提供参数 [StartingNumber] = 1,它将检查 1 是否存在,如果存在,它将检查 2 是否存在,依此类推,因此此处将返回 1。
如果 [StartNumber] = 6,该函数将返回 9。
在 C# 伪代码中,它基本上是:
int ctr = [StartingNumber]
while([SELECT NumberTaken FROM tblNumbers Where NumberTaken = ctr] != null)
ctr++;
return ctr;
该代码的问题是,如果表中有数千个数字,则看起来效率很低。另外,我可以用 C# 代码或存储过程编写它,以更有效的方式编写。
感谢您的帮助
Let's say I have an sql server table:
NumberTaken CompanyName
2 Fred
3 Fred
4 Fred
6 Fred
7 Fred
8 Fred
11 Fred
I need an efficient way to pass in a parameter [StartingNumber] and to count from [StartingNumber] sequentially until I find a number that is missing.
For example notice that 1, 5, 9 and 10 are missing from the table.
If I supplied the parameter [StartingNumber] = 1, it would check to see if 1 exists, if it does it would check to see if 2 exists and so on and so forth so 1 would be returned here.
If [StartNumber] = 6 the function would return 9.
In c# pseudo code it would basically be:
int ctr = [StartingNumber]
while([SELECT NumberTaken FROM tblNumbers Where NumberTaken = ctr] != null)
ctr++;
return ctr;
The problem with that code is that is seems really inefficient if there are thousands of numbers in the table. Also, I can write it in c# code or in a stored procedure whichever is more efficient.
Thanks for the help
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
使用
JOIN
的解决方案:A solution using
JOIN
:我将我的表称为“空白”,并使用了以下内容:
您基本上有两种情况 - 要么您的起始值丢失(因此丢失的 CTE 将包含一行),要么它存在,因此您使用递归 CTE(序列)向前计数,并从中取最大值并
从评论中添加 1 个编辑。是的,在顶部创建另一个具有过滤条件的 CTE,然后在查询的其余部分中使用它:
这现在可能会返回表中确实存在的行,但 hasEntered=1
表:
I called my table Blank, and used the following:
You basically have two cases - either your starting value is missing (so the Missing CTE will contain one row), or it's present, so you count forwards using a recursive CTE (Sequence), and take the max from that and add 1
Edit from comment. Yes, create another CTE at the top that has your filter criteria, then use that in the rest of the query:
this may now return a row that does exist in the table, but hasEntered=1
Tables:
尝试基于集合的方法 - 应该更快
这是 Sybase 语法,因此如果需要,可以对 SQL 服务器消耗进行按摩。
Try the set based approach - should be faster
This is Sybase syntax, so massage for SQL server consumption if needed.
创建一个临时表,其中包含从 StartValue 到 EndValue 的所有数字,并通过 LEFT OUTER JOIN 连接到数据表。
Create a temp table with all numbers from StartingValue to EndValue and LEFT OUTER JOIN to your data table.