উত্তর:
চমৎকার ধারণা. আমি দুটি ছোট সরলকরণের পরামর্শ দিই:
('{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)
হবে না, এটাই কথা point 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;