セットからランダムな値を設定する


11

ランダムな値をデータベースに入れる必要がありますが、完全にランダム化されたテキスト(7hfg43d3など)にしたくありません。代わりに、自分で指定した値の1つをランダムに選択します。

回答:


26

良いアイデア。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;

-> SQLfiddle

ただし、完全に安全にするために、Postgresカスタム配列添え字を使用しても、追加の追加を回避できます。

('[0:2]={Foo,Bar,Poo}'::text[])[floor(random()*3)]

SOに関するこの関連質問の下の詳細。

または、さらに良い方法trunc()として、を使用します。これは少し高速です。

('[0:2]={Foo,Bar,Poo}'::text[])[trunc(random()*3)]

ceil(0)== floor(0)+ 1?
korda 2013

@korda:私はそれに対処して、さらに追加しました。
Erwin Brandstetter 2013

@ErwinBrandstetterそれceil(random())::intは常に1を与えるので、0を返すかどうかを確認できないと思いませんか?
aki92

@ aki92:ceil(0.0)そうではない、それがポイントです。OTOH:このテストの目的のために、次のことを簡略化しますWHERE random() = 0.0
Erwin Brandstetter

@ErwinBrandstetterああ、本当です。
aki92

8

これを実現するために配列を使用するというアイデアが思いつきました。

(ARRAY['Foo','Bar','Poo'])[floor(random()*3)+1]

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;


この関数を、私が個人的にユーザーフレンドリーであると思う可変引数を持つ関数に変形できます。
Sahap Asci
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.