Vous n'êtes pas identifié(e).

#1 08/02/2018 12:55:28

mortimer.pw
Membre

Sélection aléatoire dans liste de varchar

Bonjour,
Je travaille sur un moteur 9.3 sous Cent-OS 7.
Je voudrais alimenter une table en sélectionnant aléatoirement une valeur parmi une liste de varchar.
Est-ce possible ?
Un truc du genre : select random('toto','titi','tata', ....), qui me retourne une des valeurs.
D'avance merci.

Hors ligne

#2 08/02/2018 13:53:24

ruizsebastien
Membre

Re : Sélection aléatoire dans liste de varchar

Bonjour,

En créant un type enum et en faisant du random ça marche :

create type mon_type as enum('toto','tata','titi','tutu');

SELECT mon_nom FROM unnest(enum_range(NULL::mon_type)) mon_nom ORDER BY random() LIMIT 1;

(astuce trouvée sur stackoverflow.com)

Dernière modification par ruizsebastien (08/02/2018 13:54:35)


Cordialement,

Sébastien.

Hors ligne

#3 08/02/2018 14:53:24

dverite
Membre

Re : Sélection aléatoire dans liste de varchar

VALUES ('toto'),('titi'),('tata') ORDER BY random() LIMIT 1;

Bien qu'il n'y ait pas de SELECT, c'est une requête valide qui renvoie une ligne.
Elle peut aussi être utilisée en sous-requête dans un UPDATE:

UPDATE matable SET macolonne = (VALUES ('toto'),('titi'),('tata') ORDER BY random() LIMIT 1);

Hors ligne

#4 08/02/2018 15:35:22

mortimer.pw
Membre

Re : Sélection aléatoire dans liste de varchar

Bonjour,
Merci à vous pour la rapidité de la réponse.
Pour aller plus loin, j'ai une table avec cette structure :
CREATE TABLE test (username varchar(50) NOT NULL, jour date NOT NULL);
Je souhaite l'alimenter avec une ligne par jour, avec un generate_series(timestamp '2018-01-01', '2018-02-08', '1 day'), et en plus alimenter de façon aléatoire le champ username avec mes titi, toto, ...
Est-ce que l'on peut combiner le RANDOM et le GENERATE_SERIES ?

Dernière modification par mortimer.pw (08/02/2018 15:35:38)

Hors ligne

#5 08/02/2018 15:58:39

ruizsebastien
Membre

Re : Sélection aléatoire dans liste de varchar

oui pas de problème.
voilà un exemple à adapter à votre contexte :
INSERT INTO table1 (col1,col2) SELECT round(random()*10), md5(random()::text) FROM generate_series(1, 1000000);


Cordialement,

Sébastien.

Hors ligne

#6 08/02/2018 16:21:26

mortimer.pw
Membre

Re : Sélection aléatoire dans liste de varchar

Rebonjour,
Désolé mais je n'arrive pas à appliquer.
J'ai essayé :
select (VALUES ('toto'),('titi'),('tata') ORDER BY random() LIMIT 1), ### from generate_series(timestamp '2018-01-01', '2018-02-08', '1 day');
Mais je ne sais pas comment remplacé mon ### par le jour.

Hors ligne

#7 08/02/2018 16:54:23

dverite
Membre

Re : Sélection aléatoire dans liste de varchar

Le problème est de corréler la valeur aléatoire et la date, de façon à ce que le moteur ne sorte pas une seule valeur pour toutes les dates, alors qu'il n'y a aucune corrélation "naturelle". Il y a sûrement plein de méthodes, en voici une qui me vient avec LATERAL:

select d.x,r.a
 from generate_series(timestamp '2018-01-01', '2018-02-08', '1 day') as d(x)
  join lateral (VALUES ('toto'),('titi'),('tata') ORDER BY random(),d.x limit 1) as r(a)
    on true;

Le fait d'ajouter d.x dans la clause de tri introduit une dépendance artificielle entre la 1ere et la 2nde colonne qui force postgres à recalculer la 2nde colonne à chaque ligne.

Le JOIN LATERAL est une nouveauté de la 9.3 qui justement permet d'exprimer qu'un résultat à gauche du JOIN doit être réinjecté à droite.

Hors ligne

Pied de page des forums