SQL:获取其他行未使用的数字列表

SQL:获取其他行未使用的数字列表,sql,postgresql,Sql,Postgresql,我使用的是PostgreSQL 8.1.17,我有一个带有帐号的表。帐号的可接受范围为1到1000000之间的数字,即六位数。acctnum列包含帐号。选择所有正在使用的号码很容易从tbl_acct_numbers ORDER BY acctnum中选择acctnum。我想做的是选择可接受范围内所有未使用的数字,也就是说,它们在列acctnum中的任何行中都找不到。您可以生成1-1000000之间的数字序列,然后减去查询结果 select * from generate_series(1,

我使用的是PostgreSQL 8.1.17,我有一个带有帐号的表。帐号的可接受范围为1到1000000之间的数字,即六位数。acctnum列包含帐号。选择所有正在使用的号码很容易从tbl_acct_numbers ORDER BY acctnum中选择acctnum。我想做的是选择可接受范围内所有未使用的数字,也就是说,它们在列acctnum中的任何行中都找不到。

您可以生成1-1000000之间的数字序列,然后减去查询结果

select *
  from generate_series(1, 1000000) as acctnum
  where acctnum not in (select acctnum from tbl_acct_numbers);
select * from generate_series(1,1000000)
EXCEPT
SELECT acctnum FROM tbl_acct_numbers;

你确定要这样做吗?我想你想要找到未使用的数字的原因是为了你可以使用它们

但是考虑到这些数字可能不存在,因为有人过去使用过它们,并从数据库中删除了该行。因此,如果您找到该帐号并将其重新用于一个新帐号,您可能正在分配一个以前使用过且由于某种原因被删除的帐号

如果在其他系统中存在引用该帐号的历史文档,则它们可能会错误地与使用相同帐号的新帐号关联

但是,只要您考虑了这一点,就可以通过以下方式找到未使用的id:

SELECT t1.acctnum-1 AS unused_acctnum
FROM MyTable t1
LEFT OUTER JOIN MyTable t2 ON t2.acctnum = t1.acctnum-1
WHERE t2.acctnum IS NULL;
当然,这不会找到所有未使用的帐户,只有一组比正在使用的数字少1的帐户。但这可能会给你足够的时间来工作


@Alex Howansky的答案确实会给出所有未使用的acctnums,但它可能会返回一大组行。

1000000是一个六位数的数字。。它应该是1,00000吗?不,六位数意味着一个介于000001和999999之间的数字。不包括1000000。Alex,你的查询将给出tbl_account_Number中所有不在1-1000000范围内的账号。哎哟@Rajesh,你说得对-我颠倒了查询的两面,谢谢你指出这一点。已编辑。此查询耗时519秒,但实际上与此页面上的其他查询不同。您有acctnum索引吗?你真的需要所有的数字还是10或100?如果是这样的话,使用一个限制。我实际上只需要9个数字,但以某种方式。我有一系列的数字,我需要每个范围下一个可用的数字。范围是100000-200000,200000-300000,等等。所以我可以对每个范围执行9次限制为1的查询,这就是我所做的。我把这个查询放在一个传递上下限的函数中,并调用了9次,结果就是这样。谢谢弗兰克,谢谢你的帖子——我一直在想办法,你的帖子做得很好。我对结果非常满意。确认,负号不受支持。谢谢你指出这一点。负号是Oracle版本。postGreSQl中的等价项是除了啊,好吧,那么它就可以工作了。这也是一个可以接受的解决方案,谢谢!您的推理是正确的,但在应用程序方面,我注意不要使用以前使用过的数字,因此您只看到了图片的一半。但是,此查询不适用于我,因为我的acctnum列类型不是整数,而是不同的字符。错误消息说要使用显式类型转换,但我不知道在sql中查询从未完成的类型转换时将它们放在哪里。
SELECT t1.acctnum-1 AS unused_acctnum
FROM MyTable t1
LEFT OUTER JOIN MyTable t2 ON t2.acctnum = t1.acctnum-1
WHERE t2.acctnum IS NULL;