I'm using PostgreSQL 8.1.17, and I have a table with account numbers. The acceptable range for an account number is a number between 1 and 1,000,000 (a six digit number). The column "acctnum" contains the account number. Selecting all the numbers in use is easy (SELECT acctnum FROM tbl_acct_numbers ORDER BY acctnum). What I would like to do is select all the numbers in the acceptable range that are not in use, that is, they aren't found in any rows within the column acctnum.
select *
from generate_series(1, 1000000) as acctnum
where acctnum not in (select acctnum from tbl_acct_numbers);
You can generate the series of numbers from 1-1,000,000 and then MINUS the results of your query.
select * from generate_series(1,1000000)
EXCEPT
SELECT acctnum FROM tbl_acct_numbers;
SELECT
new_number
FROM
generate_series(1, 1000000) AS new_number
LEFT JOIN tbl_acct_numbers ON new_number = acctnum
WHERE
acctnum IS NULL;
Are you sure you want to do this? I assume the reason you want to find unused numbers is so that you can use them.
But consider that the numbers might not be there because someone did use them in the past, and deleted the row from the database. So if you find that account number and re-use it for a new account, you could be assigning a number that was previously used and was deleted for a reason.
If there are any historical documents in other systems that reference that account number, they might mistakenly be associated with the new account using the same number.
However, as long as you have considered this, you can find unused id's in the following way:
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;
Granted, this doesn't find all the unused acctnums, only a set of them that are 1 less than a number that's in use. But that might give you enough to work with.
The answer from @Alex Howansky does give you all unused acctnums, but it may return a large set of rows.