Preciso colocar alguns valores aleatórios no banco de dados, mas não quero terminar com texto completamente aleatório (como 7hfg43d3). Em vez disso, gostaria de escolher aleatoriamente um dos valores fornecidos por mim.
fonte
Preciso colocar alguns valores aleatórios no banco de dados, mas não quero terminar com texto completamente aleatório (como 7hfg43d3). Em vez disso, gostaria de escolher aleatoriamente um dos valores fornecidos por mim.
Boa ideia. Sugiro duas pequenas simplificações:
('{Foo,Bar,Poo}'::text[])[ceil(random()*3)]
Sintaxe mais simples usando um array literal ( '{Foo,Bar,Poo}'::text[]
) Reduz a string para listas mais longas. Benefício adicional: declaração explícita de tipo funciona para qualquer tipo, não apenas para text
. Sua ideia original é exibida text
, porque esse é o tipo padrão para literais de strings.
Use em ceil()
vez de floor() + 1
. Mesmo resultado.
OK, teoricamente, a borda inferior pode ser 0 com precisão, conforme sugerido no seu comentário , já que random()
produz ( citando o manual aqui ):
valor aleatório no intervalo 0,0 <= x <1,0
No entanto, nunca vi isso acontecer. Execute alguns milhões de testes:
SELECT count(*)
FROM generate_series(1,1000000)
WHERE ceil(random())::int = 0;
Para ser perfeitamente seguro, você pode usar os subscritos de matriz personalizados do Postgres e ainda evitar a adição extra:
('[0:2]={Foo,Bar,Poo}'::text[])[floor(random()*3)]
Detalhes nesta pergunta relacionada ao SO.
Ou melhor ainda, o uso trunc()
, que é um pouco mais rápido.
('[0:2]={Foo,Bar,Poo}'::text[])[trunc(random()*3)]
ceil(random())::int
isso sempre lhe dará 1 para que você não possa verificar se alguma vez retornará 0?ceil(0.0)
não, esse é o ponto. OTOH: para o objectivo deste teste que pode simplificar:WHERE random() = 0.0
.Tive a ideia de usar Arrays para fazer isso:
fonte
Com base nessa idéia, criei uma função que foi bastante útil para mim:
Exemplos de uso:
SELECT random_choice(array['h', 'i', 'j', 'k', 'l']) as random_char;
SELECT random_choice((SELECT array_agg(name) FROM pets)) AS pet_name;
fonte