जवाबों:
अछा सुझाव। मैं दो मामूली सरलीकरण का सुझाव देता हूं:
('{Foo,Bar,Poo}'::text[])[ceil(random()*3)]
एक सरणी शाब्दिक ( '{Foo,Bar,Poo}'::text[]
) का उपयोग करके सरल सिंटैक्स लंबी सूची के लिए स्ट्रिंग को छोटा करता है। अतिरिक्त लाभ: स्पष्ट प्रकार की घोषणा किसी भी प्रकार के लिए काम करती है, न कि केवल इसके लिए text
। आपका मूल विचार आउटपुट के लिए होता है text
, क्योंकि यह स्ट्रिंग लीटर के लिए डिफ़ॉल्ट प्रकार है।
के ceil()
बजाय का उपयोग करें floor() + 1
। एक ही परिणाम।
ठीक है, सैद्धांतिक रूप से, निचली सीमा 0 ठीक हो सकती है, जैसा कि आपकी टिप्पणी में संकेत दिया गया है , क्योंकि random()
उत्पादन ( यहां मैनुअल को उद्धृत करते हुए ):
रेंज में यादृच्छिक मान 0.0 <= x <1.0
हालाँकि, मैंने ऐसा कभी नहीं देखा। लाख परीक्षण करें:
SELECT count(*)
FROM generate_series(1,1000000)
WHERE ceil(random())::int = 0;
पूरी तरह से सुरक्षित होने के लिए, हालांकि, आप पोस्टग्रेज कस्टम सरणी सदस्यता का उपयोग कर सकते हैं और फिर भी अतिरिक्त योग से बच सकते हैं:
('[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;