arrayspostgresqlrandomplpgsqlpostgresql-9.2

PostgreSQL PL/pgSQL random value from array of values


How can I declare an array like variable with two or three values and get them randomly during execution?

a := [1, 2, 5] -- sample sake
select random(a) -- returns random value

Any suggestion where to start?


Solution

  • CREATE OR REPLACE FUNCTION random_pick()
      RETURNS int
      LANGUAGE sql VOLATILE PARALLEL SAFE AS
    $func$
    SELECT ('[0:2]={1,2,5}'::int[])[trunc(random() * 3)::int];
    $func$;
    

    random() returns a value x where 0.0 <= x < 1.0. Multiply by 3 and truncate it with trunc() (slightly faster than floor()) to get 0, 1, or 2 with exactly equal chance.

    Postgres indexes are 1-based by default (as per SQL standard). This would be off-by-1. We could increment by 1 every time - or declare the array index to start with 0 instead. Slightly faster, yet. See:

    PARALLEL SAFE for Postgres 9.6 or later. See:

    You can use the plain SELECT statement if you don't want to create a function:

    SELECT ('[0:2]={1,2,5}'::int[])[trunc(random() * 3)::int];