Définir une valeur aléatoire à partir de l'ensemble
11
J'ai besoin de mettre des valeurs aléatoires dans la base de données, mais je ne veux pas me retrouver avec du texte complètement aléatoire (comme 7hfg43d3). Au lieu de cela, je voudrais choisir au hasard l'une des valeurs fournies par moi-même.
Bonne idée. Je suggère deux simplifications mineures:
('{Foo,Bar,Poo}'::text[])[ceil(random()*3)]
Syntaxe plus simple utilisant un tableau literal ( '{Foo,Bar,Poo}'::text[]) Raccourcit la chaîne pour les listes plus longues. Avantage supplémentaire: la déclaration de type explicite fonctionne pour tout type, pas seulement pour text. Votre idée d'origine se produit en sortie text, car c'est le type par défaut pour les littéraux de chaîne.
Utilisez ceil()au lieu de floor() + 1. Même résultat.
OK, théoriquement, la bordure inférieure pourrait être 0 précisément, comme l'indique votre commentaire , car random()produit (en citant le manuel ici ):
valeur aléatoire dans la plage 0,0 <= x <1,0
Cependant, je n'ai jamais vu cela se produire. Exécutez quelques millions de tests:
ceil(random())::int
vous donnera toujours 1 donc vous ne pourrez pas vérifier s'il retournera jamais 0?ceil(0.0)
ne serait pas, c'est le point. OTOH: dans le but de ce test , nous pourrions simplifier:WHERE random() = 0.0
.J'ai eu l'idée d'utiliser des tableaux pour accomplir cela:
la source
Sur la base de cette idée, j'ai créé une fonction qui m'a été très utile:
Exemples d'utilisation:
SELECT random_choice(array['h', 'i', 'j', 'k', 'l']) as random_char;
SELECT random_choice((SELECT array_agg(name) FROM pets)) AS pet_name;
la source