Я продублировал свой ответ от здесь :
SELECT MIN(a.id) + 1 AS firstfree
FROM (SELECT id FROM table UNION SELECT 0) a
LEFT JOIN table b ON b.id = a.id + 1
WHERE b.id IS NULL
Это обрабатывает все случаи, о которых я могу подумать, включая отсутствие существующих записей.
Единственное, что мне не нравится в этом решении, это то, что дополнительные условия должны быть включены дважды, например:
SELECT MIN(a.id) + 1 AS firstfree
FROM (SELECT id FROM table WHERE column = 4711 UNION SELECT 0) a
LEFT JOIN table b ON b.column = 4711 AND b.id = a.id + 1
WHERE b.id IS NULL
Также обратите внимание на комментарии о блокировке и параллелизме - требование заполнить пробелы в большинстве случаев является плохим дизайном и может вызвать проблемы. Однако у меня была веская причина сделать это: идентификаторы должны быть напечатаны и напечатаны людьми, и мы не хотим, чтобы через некоторое время идентификаторы имели много цифр, в то время как все младшие цифры свободны ...