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
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:
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$;