Есть способ делать то, что вы хотите с рекурсивными запросами, увы, это нехорошо.
Предположим, у вас есть следующая таблица:
CREATE TABLE test (a int)
Для упрощения вы хотите вставить случайные числа от 0 до 4 (random() * 5)::int
, которых нет в таблице.
WITH RECURSIVE rand (i, r, is_new) AS (
SELECT
0,
null,
false
UNION ALL
SELECT
i + 1,
next_number.v,
NOT EXISTS (SELECT 1 FROM test WHERE test.a = next_number.v)
FROM
rand r,
(VALUES ((random() * 5)::int)) next_number(v)
-- safety check to make sure we do not go into an infinite loop
WHERE i < 500
)
SELECT * FROM rand WHERE rand.is_new LIMIT 1
Я не уверен, но PostgreSQL должен быть в состоянии прекратить итерации, когда у него будет один результат, так как он знает, что запрос имеет ограничение 1.
Хорошая особенность этого запроса в том, что вы можете заменить (random() * 5)::int
на любую функцию генерации идентификатора, которую вы хотите