Postgres FOR LOOP Postgres FOR LOOP postgresql postgresql

Postgres FOR LOOP


Procedural elements like loops are not part of the SQL language and can only be used inside the body of a procedural language function, procedure (Postgres 11 or later) or a DO statement, where such additional elements are defined by the respective procedural language. The default is PL/pgSQL, but there are others.

Example with plpgsql:

DO$do$BEGIN    FOR i IN 1..25 LOOP      INSERT INTO playtime.meta_random_sample         (col_i, col_id)                       -- declare target columns!      SELECT  i,     id      FROM   tbl      ORDER  BY random()      LIMIT  15000;   END LOOP;END$do$;

For many tasks that can be solved with a loop, there is a shorter and faster set-based solution around the corner. Pure SQL equivalent for your example:

INSERT INTO playtime.meta_random_sample (col_i, col_id)SELECT t.*FROM   generate_series(1,25) iCROSS  JOIN LATERAL (   SELECT i, id   FROM   tbl   ORDER  BY random()   LIMIT  15000   ) t;

About generate_series():

About optimizing performance of random selections:


Below is example you can use:

create temp table test2 (  id1  numeric,  id2  numeric,  id3  numeric,  id4  numeric,  id5  numeric,  id6  numeric,  id7  numeric,  id8  numeric,  id9  numeric,  id10 numeric) with (oids = false);do$do$declare     i int;beginfor  i in 1..100000loop    insert into test2  values (random(), i * random(), i / random(), i + random(), i * random(), i / random(), i + random(), i * random(), i / random(), i + random());end loop;end;$do$;


I just ran into this question and, while it is old, I figured I'd add an answer for the archives. The OP asked about for loops, but their goal was to gather a random sample of rows from the table. For that task, Postgres 9.5+ offers the TABLESAMPLE clause on WHERE. Here's a good rundown:

https://www.2ndquadrant.com/en/blog/tablesample-in-postgresql-9-5-2/

I tend to use Bernoulli as it's row-based rather than page-based, but the original question is about a specific row count. For that, there's a built-in extension:

https://www.postgresql.org/docs/current/tsm-system-rows.html

CREATE EXTENSION tsm_system_rows;

Then you can grab whatever number of rows you want:

select * from playtime tablesample system_rows (15);