回答:
良いアイデア。2つの小さな簡略化を提案します。
('{Foo,Bar,Poo}'::text[])[ceil(random()*3)]
配列リテラル('{Foo,Bar,Poo}'::text[]
)を使用した単純な構文長いリストの文字列を短くします。追加の利点:明示的な型宣言は、だけでなく、どの型でも機能しますtext
。これtext
は文字列リテラルのデフォルトのタイプであるため、元のアイデアはoutput です。
のceil()
代わりに使用しますfloor() + 1
。同じ結果。
示唆したようOK、理論的には、下の境界線は、正確に0かもしれないあなたのコメントから、random()
生成し(ここでは、マニュアルを引用します):
0.0 <= x <1.0の範囲のランダムな値
しかし、私はそれが起こるのを見たことがありません。数百万のテストを実行します。
SELECT count(*)
FROM generate_series(1,1000000)
WHERE ceil(random())::int = 0;
ただし、完全に安全にするために、Postgresカスタム配列添え字を使用しても、追加の追加を回避できます。
('[0:2]={Foo,Bar,Poo}'::text[])[floor(random()*3)]
または、さらに良い方法trunc()
として、を使用します。これは少し高速です。
('[0:2]={Foo,Bar,Poo}'::text[])[trunc(random()*3)]
ceil(random())::int
は常に1を与えるので、0を返すかどうかを確認できないと思いませんか?
ceil(0.0)
そうではない、それがポイントです。OTOH:このテストの目的のために、次のことを簡略化しますWHERE random() = 0.0
。
この考えに基づいて、私にとって非常に便利な関数を作成しました。
CREATE OR REPLACE FUNCTION random_choice(
choices text[]
)
RETURNS text AS $$
DECLARE
size_ int;
BEGIN
size_ = array_length(choices, 1);
RETURN (choices)[floor(random()*size_)+1];
END
$$ LANGUAGE plpgsql;
使用例:
SELECT random_choice(array['h', 'i', 'j', 'k', 'l']) as random_char;
SELECT random_choice((SELECT array_agg(name) FROM pets)) AS pet_name;