web-dev-qa-db-fra.com

Postgres POUR LOOP

J'essaie d'obtenir 25 échantillons aléatoires de 15 000 ID d'une table. Au lieu d'appuyer manuellement sur exécuter à chaque fois, j'essaie de faire une boucle. Ce que je comprends parfaitement, ce n'est pas l'utilisation optimale de Postgres, mais c'est l'outil dont je dispose. Voici ce que j'ai jusqu'à présent:

for i in 1..25 LOOP
   insert into playtime.meta_random_sample
   select i, ID
   from   tbl
   order  by random() limit 15000
end loop
45
user2840106

Eléments procéduraux tels que boucles ne font pas partie du langage SQL et ne peut être utilisé que dans le corps d'un langage procédural fonction , procédure (Postgres 11 ou ultérieure) ou un DO , où ces éléments supplémentaires sont définis par le langage procédural correspondant. La valeur par défaut est PL/pgSQL , mais il y en a d'autres .

Exemple avec 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$;

Pour de nombreuses tâches pouvant être résolues avec une boucle, il existe une solution plus courte et plus rapide au coin de la rue. Pure SQL équivalent pour votre exemple:

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

À propos de generate_series() :

À propos de l'optimisation des performances des sélections aléatoires:

108

Vous trouverez ci-dessous des exemples que vous pouvez utiliser:

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;
begin
for  i in 1..100000
loop
    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$;
0
Gabriel