ตั้งค่าสุ่มจากชุด


11

ฉันต้องใส่ค่าสุ่มลงในฐานข้อมูล แต่ฉันไม่ต้องการที่จะจบลงด้วยข้อความที่สุ่มสมบูรณ์ (เช่น 7hfg43d3) แต่ฉันต้องการสุ่มเลือกค่าหนึ่งค่าที่จัดทำโดยตัวเอง

คำตอบ:


26

ความคิดดี. ฉันขอแนะนำการทำให้เข้าใจง่ายสองข้อเล็กน้อย:

('{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;

-> SQLfiddle

เพื่อความปลอดภัยอย่างสมบูรณ์แบบคุณสามารถใช้ตัวห้อยอาร์เรย์แบบกำหนดเองของ Postgres และยังคงหลีกเลี่ยงการเพิ่มพิเศษ:

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

รายละเอียดภายใต้คำถามที่เกี่ยวข้องใน SO

หรือดีกว่ายังใช้งานtrunc(), ที่บิตเร็วขึ้น

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

ceil (0) == ชั้น (0) + 1?
korda

@korda: ฉันเพิ่มมากขึ้นโดยกล่าวว่า
Erwin Brandstetter

@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;


คุณสามารถ morph ฟังก์ชั่นนี้เป็นฟังก์ชั่นที่มีพารามิเตอร์variadicซึ่งผมเองพบว่าผู้ใช้ที่เป็นมิตรมากขึ้น
Sahap Asci
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.