2010-09-29 2 views
2

Я использую PostgreSQL 8.1.17, и у меня есть таблица с номерами счетов. Допустимый диапазон для номера счета - это номер от 1 до 1 000 000 (шестизначное число). Столбец «acctnum» содержит номер учетной записи. Выбор всех используемых чисел легко (SELECT acctnum FROM tbl_acct_numbers ORDER BY acctnum). То, что я хотел бы сделать, - это выбрать все числа в допустимом диапазоне, которые не используются, то есть они не найдены ни в каких строках внутри столбца acctnum.SQL: Получить список чисел, которые не используются другими строками

+0

1,000,000 (шестизначное число) .. Предполагается, что оно составляет 1 000 000? –

+0

Нет, шестизначное число означает число от 000001 до 999999. Не включая 1,000,000. – Pyrite

ответ

4
SELECT 
    new_number 
FROM 
    generate_series(1, 1000000) AS new_number 
     LEFT JOIN tbl_acct_numbers ON new_number = acctnum 
WHERE 
    acctnum IS NULL; 
+1

Этот запрос занял 519 секунд, но на самом деле работал в отличие от некоторых других на этой странице. – Pyrite

+0

У вас есть указатель на acctnum? И вам действительно нужны ВСЕ номера или всего 10 или 100? Если это так, используйте LIMIT. –

+0

Мне действительно нужны только 9 чисел, но определенным образом. У меня есть диапазоны чисел, и мне нужен следующий доступный номер для каждого диапазона. Диапазон составляет 100 000 - 200 000, 200 000 - 300 000 и т. Д. Таким образом, я мог выполнить этот запрос с LIMIT 1 для каждого диапазона 9 раз, что я и сделал. Я поставил этот запрос в функцию, проходящую в нижней/верхней границах, и вызвал ее 9 раз, и там у меня она есть. Благодаря! – Pyrite

0
select * 
    from generate_series(1, 1000000) as acctnum 
    where acctnum not in (select acctnum from tbl_acct_numbers); 
+0

Alex, ваш запрос даст все номера счетов в tbl_account_numbers, которые не находятся в диапазоне 1-1000000. –

+0

Упс @ Раджеш, ты прав. Я получил две стороны запроса в обратном порядке, спасибо, что указали это. (Отредактировано.) –

0

Вы можете создать серию чисел от 1 до 1 000 000, а затем MINUS - результаты вашего запроса.

select * from generate_series(1,1000000) 
EXCEPT 
SELECT acctnum FROM tbl_acct_numbers; 
+0

MINUS не будет работать в PostgreSQL –

+0

Подтверждено, MINUS не поддерживается. – Pyrite

+0

Спасибо, что указали это. MINUS - версия Oracle. Квивалент в postGreSQl «ЗА ИСКЛЮЧЕНИЕМ» http://www.faqs.org/docs/ppbook/x5802.htm#USINGEXCEPT –

1

Вы уверены, что хотите это сделать? Я предполагаю, что причина, по которой вы хотите найти неиспользуемые номера, - это то, что вы можете их использовать.

Но учтите, что цифр может не быть, потому что кто-то сделал использовать их в прошлом и удалил строку из базы данных. Поэтому, если вы найдете этот номер учетной записи и повторно используете его для новой учетной записи, вы можете назначить номер, который ранее использовался и был удален по какой-либо причине.

Если в других системах, которые ссылаются на этот номер счета, есть какие-либо исторические документы, они могут ошибочно ассоциироваться с новой учетной записью с использованием того же номера.

Однако, до тех пор, как вы считали это, вы можете найти неиспользуемые идентификаторы следующим образом:

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; 

Конечно, это не находит все неиспользуемые acctnums, только их набор которые на 1 меньше числа, которое используется. Но это может дать вам достаточно для работы.


Ответ от @Alex Howansky действительно дает вам все неиспользованные acctnums, но он может быть возвращен большой набор строк.

+0

Ваши рассуждения верны, но со стороны приложения я стараюсь не использовать числа, которые использовались раньше, поэтому вы видите только половину изображения. Этот запрос не работал для меня, потому что мой тип col для acctnum не является целым числом, но характер меняется. В сообщении об ошибке говорится, что для использования явных типов применяются разные типы, но я не знаю, куда их помещать в запрос (никогда не выполнялось литье типов в sql). – Pyrite

Смежные вопросы