2016-03-08 1 views
0

У меня есть эта таблица PostgreSQLнайти наименьший доступный номер в столбце базы данных PostgreSQL

--------------------------------- 
| id | tag | name | 
--------------------------------- 
| 1 | 1 | name1 | 
| 3 | 3 | name3 | 
| 4 | 4 | name4 | 
| 6 | 6 | name6 | 
| 7 | 7 | name7 | 

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

в таблице выше клиент с идентификаторами № 2 и 5 был удален некоторое время назад. теперь я собираюсь вставить нового клиента и хочу, чтобы база данных находила для меня самый низкий доступный номер тега (в данном случае это будет №2), чтобы я мог повторно использовать его для следующего клиента.

как?

последняя NpgSQL 3.0.5 и PostgreSQL 9.5

+0

Возможный дубликат: http://stackoverflow.com/questions/174532/how-to-find-holes-in-a-table – jdabrowski

ответ

1

С ROW_NUMBER(), вы должны быть в состоянии сделать это довольно быстро;

SELECT rn tag             
FROM (SELECT tag, ROW_NUMBER() OVER (ORDER BY tag) rn FROM Table1) z 
WHERE rn != tag                 
ORDER BY rn OFFSET 0 ROW FETCH NEXT 1 ROW ONLY; 

Это в основном получает тег в цифровом порядке вместе с номером строки, и возвращает первый номер строки, который не соответствует его строке тега (например, если теги 1,2,4 существует, они будут получать строку номер 1,2,3 и 3 - это номер первой строки, который не соответствует его тегу, 4)

An SQLfiddle to test with.

Слово предупреждения, однако, установите тег, уникальный в базе данных, и будьте готовы повторить попытку, если у вас есть 2 человека, добавляющих клиентов в одно и то же время, оба человека получат самый низкий тег назад, но только одному будет разрешено установите его на своих клиентов. В противном случае у двух клиентов может быть один и тот же тег, что, вероятно, плохо.

+0

, что работал, я должен был изменить «OFFSET 0 "to" OFFSET 1 ", потому что теги начинаются с 0 и номера строк начинаются с 1 – docesam

+0

@docesam Я думаю, что ... ... (ORDER BY tag) - 1 rn FROM ...' может быть лучше в этом случае. –

+0

спасибо. почему это должно быть лучше? – docesam

1
select tag 
from (
    select generate_series (1, (select max(tag) from customer)) as tag 
    except 
    select tag from customer 
) s 
order by tag 
limit 1 

SQL Fiddle

+0

это тоже сработало. благодаря – docesam