Генерация случайного числа не дублированного случайного числа в [0, 1001] через цикл - PullRequest
8 голосов
/ 29 ноября 2011

Мне нужно сгенерировать случайное число недублированных случайных чисел в plpgsql.Недублированное число должно находиться в диапазоне [1,1001].Однако код генерирует число, превышающее 1001.

directed2number := trunc(Random()*7+1);
counter := directed2number
while counter > 0
loop
to_point := trunc((random() * 1/directed2number - counter/directed2number + 1) * 1001 +1);
...
...
counter := counter - 1;
end loop;

Ответы [ 2 ]

3 голосов
/ 30 ноября 2011

Если я правильно понял

  • Вам нужно случайное число ( 1 до 8 ) случайных чисел.
  • Случайные числа охватывают 1 до 1001 .
  • Случайные числа должны быть уникальными . Никто не должен появляться более одного раза.

CREATE OR REPLACE FUNCTION x.unique_rand_1001()
RETURNS SETOF integer AS
$body$
DECLARE
    nrnr    int := trunc(random()*7+1);  -- number of numbers
BEGIN

    RETURN QUERY
    SELECT (1000 * random())::integer + 1
    FROM   generate_series(1, nrnr*2)
    GROUP  BY 1
    LIMIT  nrnr;

END;
$body$ LANGUAGE plpgsql VOLATILE;

Звоните:

SELECT x.unique_rand_1001();

Номера сделаны уникальными GROUP BY. Я генерирую вдвое больше чисел, сколько необходимо, чтобы обеспечить достаточное количество чисел в случае удаления дубликатов. При заданных размерах задачи (макс. 8 из 1001 чисел) маловероятно, чтобы осталось недостаточно чисел. В худшем случае: возвращаются номера зрителей.

1 голос
/ 29 ноября 2011

Я бы не стал так подходить к проблеме в PostgreSQL. Кажется, что-то в этом направлении имеет больше смысла.

-- Returns a random integer in the interval [n, m].
CREATE OR REPLACE FUNCTION random_integer(integer, integer)
  RETURNS integer AS
$BODY$
   select trunc( $1 + (($2*random()) ))::integer
$BODY$
  LANGUAGE sql VOLATILE

Затем, чтобы выбрать одно случайное целое число от 1 до 1000,

select random_integer(1, 1000);

Чтобы выбрать 100 случайных целых чисел от 1 до 1000,

select random_integer(1, 1000)
from generate_series(1,100);
...