postgresql: Как получить существующий идентификатор из непоследовательных идентификаторов таблицы - PullRequest
2 голосов
/ 13 мая 2019

Postgresql версия 9.4

У меня есть таблица с целочисленным столбцом, в которой есть число целых чисел с некоторыми пробелами, как в примере ниже;Я пытаюсь получить существующий идентификатор из столбца в произвольном порядке с помощью следующего запроса, но иногда он возвращает NULL:

CREATE TABLE
IF NOT EXISTS test_tbl(
    id INTEGER);
INSERT INTO test_tbl
VALUES (10),
       (13),
       (14),
       (16),
       (18),
       (20);
-------------------------------    
SELECT * FROM test_tbl;

-------------------------------    
SELECT COALESCE(tmp.id, 20) AS classification_id
FROM (
       SELECT tt.id,
              row_number() over(
       ORDER BY tt.id) AS row_num
       FROM test_tbl tt
     ) tmp
WHERE tmp.row_num =floor(random() * 10);

Пожалуйста, дайте мне знать, где я делаю неправильно.

Ответы [ 2 ]

0 голосов
/ 13 мая 2019

, но иногда возвращается NULL

и я должен добавить к этому, что он иногда возвращает более 1 строки, верно?в данных образца есть 6 строк, поэтому столбец row_num будет иметь значение от 1 до 6.Это:

floor(random() * 10)

создает случайное число от 0 до 0,9999 ...Вы должны использовать:

floor(random() * 6 + 1)::int

, чтобы получить случайное целое число от 1 до 6.Но это не решило бы проблему, потому что предложение WHERE выполняется один раз для каждой строки, поэтому есть случай, когда row_num никогда не совпадет с созданным случайным числом, поэтому он вернет ничто , или егобудет соответствовать более одного раза, поэтому он вернет более 1 строки .Смотрите демо .Правильный (хотя иногда и не самый эффективный) способ получения случайной строки:

SELECT id FROM test_tbl ORDER BY random() LIMIT 1

Также проверьте другие ссылки из SO, например: быстрый выбор случайной строки в Postgres

0 голосов
/ 13 мая 2019

Вы можете выбрать одну строку и порядок на random(), таким образом, вы гарантированно попадете в существующую строку

select id
from test_tbl
order by random()
LIMIT 1;
...