ฉันจะขอสุ่มแถว (หรือใกล้เคียงกับการสุ่มอย่างแท้จริงเท่าที่จะทำได้) ใน SQL บริสุทธิ์ได้อย่างไร
ฉันจะขอสุ่มแถว (หรือใกล้เคียงกับการสุ่มอย่างแท้จริงเท่าที่จะทำได้) ใน SQL บริสุทธิ์ได้อย่างไร
คำตอบ:
ดูโพสต์นี้: SQL เพื่อเลือกแถวสุ่มจากตารางฐานข้อมูล มันจะผ่านวิธีการในการทำสิ่งนี้ใน MySQL, PostgreSQL, Microsoft SQL Server, IBM DB2 และ Oracle (ต่อไปนี้ถูกคัดลอกมาจากลิงค์นั้น):
เลือกแถวสุ่มด้วย MySQL:
SELECT column FROM table
ORDER BY RAND()
LIMIT 1
เลือกแถวสุ่มด้วย PostgreSQL:
SELECT column FROM table
ORDER BY RANDOM()
LIMIT 1
เลือกแถวสุ่มด้วย Microsoft SQL Server:
SELECT TOP 1 column FROM table
ORDER BY NEWID()
เลือกแถวสุ่มด้วย IBM DB2
SELECT column, RAND() as IDX
FROM table
ORDER BY IDX FETCH FIRST 1 ROWS ONLY
เลือกบันทึกแบบสุ่มด้วย Oracle:
SELECT column FROM
( SELECT column FROM table
ORDER BY dbms_random.value )
WHERE rownum = 1
ORDER BY RAND()
ผิด ...
O(n)
กับn
จำนวนระเบียนในตาราง ลองนึกภาพคุณมี 1 ล้านบันทึกคุณต้องการสร้างตัวเลขสุ่ม 1 ล้านตัวหรือรหัสเฉพาะหรือไม่? ฉันควรใช้COUNT()
และเกี่ยวข้องกับมันในการLIMIT
แสดงออกใหม่ด้วยตัวเลขสุ่มเดียว
โซลูชันอย่าง Jeremies:
SELECT * FROM table ORDER BY RAND() LIMIT 1
ทำงาน แต่พวกเขาต้องการการสแกนตามลำดับของตารางทั้งหมด (เนื่องจากค่าแบบสุ่มที่เกี่ยวข้องกับแต่ละแถวจำเป็นต้องคำนวณ - เพื่อให้สามารถหาค่าที่เล็กที่สุดได้) ซึ่งอาจช้ามากสำหรับตารางขนาดกลาง คำแนะนำของฉันจะใช้คอลัมน์ตัวเลขที่จัดทำดัชนีบางชนิด (ตารางจำนวนมากมีสิ่งเหล่านี้เป็นคีย์หลัก) แล้วเขียนดังนี้:
SELECT * FROM table WHERE num_value >= RAND() *
( SELECT MAX (num_value ) FROM table )
ORDER BY num_value LIMIT 1
สิ่งนี้ใช้ได้ในเวลาลอการิทึมโดยไม่คำนึงถึงขนาดของตารางหากnum_value
ถูกทำดัชนี คำเตือน: นี้สันนิษฐานว่ามีการกระจายอย่างเท่าเทียมกันในช่วงnum_value
0..MAX(num_value)
หากชุดข้อมูลของคุณเบี่ยงเบนไปจากสมมติฐานนี้คุณจะได้รับผลลัพธ์ที่เบ้ (บางแถวจะปรากฏบ่อยกว่าชุดอื่น ๆ )
ฉันไม่รู้ว่ามันมีประสิทธิภาพเพียงใด แต่ฉันเคยใช้มาก่อน:
SELECT TOP 1 * FROM MyTable ORDER BY newid()
เนื่องจาก GUID นั้นเป็นแบบสุ่มการสั่งซื้อจึงหมายความว่าคุณจะได้แถวแบบสุ่ม
ORDER BY RAND() LIMIT 1
TOP 1
newid()
ORDER BY NEWID()
ใช้เวลา 7.4 milliseconds
WHERE num_value >= RAND() * (SELECT MAX(num_value) FROM table)
ใช้เวลา0.0065 milliseconds
!
ฉันจะไปด้วยวิธีหลังแน่นอน
rand()
ส่งกลับจำนวนจุดลอยตัวที่n
0 < n < 1
สมมติว่าnum_value
เป็นจำนวนเต็มค่าส่งคืนของrand() * max(num_value)
จะถูกบังคับให้เป็นจำนวนเต็มดังนั้นการตัดทอนอะไรก็ได้หลังจากจุดทศนิยม ดังนั้นrand() * max(num_value)
จะน้อยกว่าเสมอmax(num_value)
ซึ่งเป็นสาเหตุที่แถวสุดท้ายจะไม่ถูกเลือก
คุณไม่ได้พูดว่าคุณใช้เซิร์ฟเวอร์ตัวใด ใน SQL Server เวอร์ชันเก่าคุณสามารถใช้สิ่งนี้:
select top 1 * from mytable order by newid()
ใน SQL Server 2005 และสูงกว่าคุณสามารถใช้TABLESAMPLE
เพื่อรับตัวอย่างสุ่มที่ทำซ้ำได้:
SELECT FirstName, LastName
FROM Contact
TABLESAMPLE (1 ROWS) ;
สำหรับ SQL Server
newid () / order by จะทำงานได้ แต่จะมีราคาแพงมากสำหรับชุดผลลัพธ์ขนาดใหญ่เพราะต้องสร้างรหัสสำหรับทุกแถวแล้วเรียงลำดับ
TABLESAMPLE () เป็นสิ่งที่ดีจากจุดยืนด้านประสิทธิภาพ แต่คุณจะได้รับผลลัพธ์จำนวนมาก (แถวทั้งหมดในหน้าจะถูกส่งคืน)
สำหรับตัวอย่างสุ่มจริงที่มีประสิทธิภาพดีกว่าวิธีที่ดีที่สุดคือกรองแถวแบบสุ่ม ฉันพบตัวอย่างโค้ดต่อไปนี้ในบทความ SQL Server Books Online การจำกัด ชุดผลลัพธ์โดยใช้ TABLESAMPLE :
หากคุณต้องการสุ่มตัวอย่างแถวแต่ละแถวจริงๆให้แก้ไขแบบสอบถามเพื่อกรองแถวแบบสุ่มแทนที่จะใช้ TABLESAMPLE ตัวอย่างเช่นแบบสอบถามต่อไปนี้ใช้ฟังก์ชัน NEWID เพื่อส่งกลับประมาณหนึ่งเปอร์เซ็นต์ของแถวของตาราง Sales.SalesOrderDetail:
SELECT * FROM Sales.SalesOrderDetail WHERE 0.01 >= CAST(CHECKSUM(NEWID(),SalesOrderID) & 0x7fffffff AS float) / CAST (0x7fffffff AS int)
คอลัมน์ SalesOrderID จะรวมอยู่ในนิพจน์ CHECKSUM เพื่อให้ NEWID () ประเมินหนึ่งครั้งต่อแถวเพื่อให้ได้การสุ่มตัวอย่างตามแต่ละแถว นิพจน์ CAST (CHECKSUM (NEWID (), SalesOrderID) & 0x7fffffff AS float / CAST (0x7fffffff AS int) ประเมินค่าเป็นทศนิยมแบบสุ่มระหว่าง 0 และ 1
เมื่อทำงานกับตารางที่มี 1,000,000 แถวผลลัพธ์ของฉันคือ
SET STATISTICS TIME ON
SET STATISTICS IO ON
/* newid()
rows returned: 10000
logical reads: 3359
CPU time: 3312 ms
elapsed time = 3359 ms
*/
SELECT TOP 1 PERCENT Number
FROM Numbers
ORDER BY newid()
/* TABLESAMPLE
rows returned: 9269 (varies)
logical reads: 32
CPU time: 0 ms
elapsed time: 5 ms
*/
SELECT Number
FROM Numbers
TABLESAMPLE (1 PERCENT)
/* Filter
rows returned: 9994 (varies)
logical reads: 3359
CPU time: 641 ms
elapsed time: 627 ms
*/
SELECT Number
FROM Numbers
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), Number) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
หากคุณสามารถใช้งาน TABLESAMPLE ได้มันจะให้ประสิทธิภาพที่ดีที่สุดแก่คุณ มิฉะนั้นใช้วิธี newid () / filter newid () / คำสั่งซื้อควรเป็นทางเลือกสุดท้ายหากคุณมีชุดผลลัพธ์จำนวนมาก
หากเป็นไปได้ให้ใช้ข้อความสั่งที่เก็บไว้เพื่อหลีกเลี่ยงความไม่มีประสิทธิภาพของดัชนีทั้งสองใน RND () และสร้างฟิลด์หมายเลขบันทึก
เตรียมการบันทึกแบบสุ่มจาก "SELECT * จากข้อ จำกัด ของตาราง?, 1"; SET @ n = ชั้น (RAND () * (เลือก COUNT (*) จากตาราง)); ดำเนินการ RandomRecord โดยใช้ @n;
วิธีที่ดีที่สุดคือการใส่ค่าแบบสุ่มในคอลัมน์ใหม่เพื่อจุดประสงค์นั้นและใช้บางอย่างเช่นนี้ (รหัสเทียม + SQL):
randomNo = random()
execSql("SELECT TOP 1 * FROM MyTable WHERE MyTable.Randomness > $randomNo")
นี่เป็นโซลูชันที่ใช้งานโดยรหัส MediaWiki แน่นอนว่ามีอคติต่อค่าที่น้อยกว่า แต่พวกเขาพบว่ามันเพียงพอที่จะตัดค่าสุ่มรอบเป็นศูนย์เมื่อไม่มีการเรียกแถว
โซลูชั่น newid () อาจต้องใช้การสแกนแบบเต็มตารางเพื่อให้แต่ละแถวสามารถกำหนด guid ใหม่ซึ่งจะมีประสิทธิภาพน้อยกว่ามาก
rand () solution อาจไม่ทำงานเลย (เช่นกับ MSSQL) เพราะฟังก์ชั่นจะได้รับการประเมินเพียงครั้งเดียวและทุกแถวจะได้รับหมายเลข "สุ่ม" เดียวกัน
สำหรับ SQL Server 2005 และ 2008 ถ้าเราต้องการตัวอย่างสุ่มของแต่ละแถว (จากBooks Online ):
SELECT * FROM Sales.SalesOrderDetail
WHERE 0.01 >= CAST(CHECKSUM(NEWID(), SalesOrderID) & 0x7fffffff AS float)
/ CAST (0x7fffffff AS int)
กรณีที่ใช้ RAND () เนื่องจากไม่ได้รับการสนับสนุนคุณอาจได้รับ ID สูงสุด (= สูงสุด)
SELECT MAX(ID) FROM TABLE;
รับการสุ่มระหว่าง 1..Max (= My_Generated_Random)
My_Generated_Random = rand_in_your_programming_lang_function(1..Max);
จากนั้นเรียกใช้ SQL นี้:
SELECT ID FROM TABLE WHERE ID >= My_Generated_Random ORDER BY ID LIMIT 1
โปรดทราบว่ามันจะตรวจสอบแถวใด ๆ ที่รหัสเท่ากับหรือสูงกว่าค่าที่เลือก นอกจากนี้ยังเป็นไปได้ที่จะค้นหาแถวในตารางและรับ ID ที่เท่ากันหรือต่ำกว่า My_Generated_Random จากนั้นปรับเปลี่ยนแบบสอบถามเช่นนี้:
SELECT ID FROM TABLE WHERE ID <= My_Generated_Random ORDER BY ID DESC LIMIT 1
ตามที่ระบุไว้ในความคิดเห็นของ @ BillKarwin ในคำตอบของ @ cnu ...
เมื่อรวมกับ LIMIT ฉันพบว่ามันทำงานได้ดีขึ้นมาก (อย่างน้อยกับ PostgreSQL 9.1) เพื่อเข้าร่วมกับการสั่งซื้อแบบสุ่มแทนที่จะสั่งซื้อแถวจริงโดยตรง: เช่น
SELECT * FROM tbl_post AS t
JOIN ...
JOIN ( SELECT id, CAST(-2147483648 * RANDOM() AS integer) AS rand
FROM tbl_post
WHERE create_time >= 1349928000
) r ON r.id = t.id
WHERE create_time >= 1349928000 AND ...
ORDER BY r.rand
LIMIT 100
ตรวจสอบให้แน่ใจว่า 'r' สร้างค่า 'rand' สำหรับทุกค่าคีย์ที่เป็นไปได้ในเคียวรีที่ซับซ้อนซึ่งรวมอยู่ด้วย แต่ยังคง จำกัด จำนวนแถวของ 'r' เท่าที่เป็นไปได้
CAST as Integer มีประโยชน์อย่างยิ่งสำหรับ PostgreSQL 9.2 ซึ่งมีการเพิ่มประสิทธิภาพการเรียงลำดับเฉพาะสำหรับประเภทจำนวนเต็มและจำนวนทศนิยมที่แม่นยำ
โซลูชันส่วนใหญ่ที่นี่มีเป้าหมายเพื่อหลีกเลี่ยงการเรียงลำดับ แต่พวกเขายังคงต้องทำการสแกนตามลำดับบนตาราง
นอกจากนี้ยังมีวิธีหลีกเลี่ยงการสแกนตามลำดับโดยเปลี่ยนเป็นการสแกนดัชนี หากคุณรู้ค่าดัชนีของแถวสุ่มของคุณคุณจะได้รับผลลัพธ์เกือบจะทันที ปัญหาคือ - วิธีการเดาค่าดัชนี
วิธีแก้ปัญหาต่อไปนี้ใช้กับ PostgreSQL 8.4:
explain analyze select * from cms_refs where rec_id in
(select (random()*(select last_value from cms_refs_rec_id_seq))::bigint
from generate_series(1,10))
limit 1;
ฉันแก้ปัญหาข้างต้นคุณเดา 10 ค่าดัชนีสุ่มต่าง ๆ จากช่วง 0 .. [ค่าสุดท้ายของ id]
หมายเลข 10 นั้นเป็นกฎเกณฑ์ - คุณอาจใช้ 100 หรือ 1,000 ก็ได้ (น่าอัศจรรย์) ไม่มีผลกระทบต่อเวลาตอบสนอง
นอกจากนี้ยังมีปัญหาอย่างใดอย่างหนึ่ง - ถ้าคุณมีรหัสเบาบางคุณอาจจะพลาด วิธีแก้ปัญหาคือมีแผนสำรองข้อมูล :) ในกรณีนี้การสั่งซื้อแบบเก่าโดยการสุ่ม () แบบสอบถาม เมื่อ id ที่รวมกันมีลักษณะเช่นนี้:
explain analyze select * from cms_refs where rec_id in
(select (random()*(select last_value from cms_refs_rec_id_seq))::bigint
from generate_series(1,10))
union all (select * from cms_refs order by random() limit 1)
limit 1;
ไม่ใช่สหภาพ ข้อทั้งหมด ในกรณีนี้ถ้าส่วนแรกส่งคืนข้อมูลใด ๆ ส่วนที่สองจะไม่ถูกประหาร!
ช่วงปลายปี แต่มาถึงที่นี่ผ่าน Google ดังนั้นเพื่อลูกหลานฉันจะเพิ่มทางเลือกอื่น
อีกวิธีคือใช้ท็อปสองครั้งโดยสลับคำสั่งซื้อ ฉันไม่รู้ว่ามันเป็น "pure SQL" หรือไม่เพราะใช้ตัวแปรใน TOP แต่ทำงานได้ใน SQL Server 2008 นี่คือตัวอย่างที่ฉันใช้เทียบกับคำในพจนานุกรมถ้าฉันต้องการคำแบบสุ่ม
SELECT TOP 1
word
FROM (
SELECT TOP(@idx)
word
FROM
dbo.DictionaryAbridged WITH(NOLOCK)
ORDER BY
word DESC
) AS D
ORDER BY
word ASC
แน่นอน @idx เป็นจำนวนเต็มที่สร้างแบบสุ่มซึ่งมีช่วงตั้งแต่ 1 ถึง COUNT (*) บนตารางเป้าหมายโดยรวม หากคอลัมน์ของคุณได้รับการจัดทำดัชนีคุณจะได้รับประโยชน์เช่นกัน ข้อดีอีกอย่างคือคุณสามารถใช้ในฟังก์ชั่นได้เนื่องจาก NEWID () ไม่ได้รับอนุญาต
สุดท้ายแบบสอบถามข้างต้นจะทำงานในเวลาประมาณ 1/10 ของเวลา exec ของ NEWID () - ประเภทของแบบสอบถามในตารางเดียวกัน YYMV
คุณอาจลองใช้new id()
ฟังก์ชั่น
เพียงแค่เขียนแบบสอบถามของคุณและใช้การเรียงลำดับตามnew id()
ฟังก์ชั่น มันค่อนข้างสุ่ม
สำหรับ MySQL ที่จะได้รับการบันทึกแบบสุ่ม
SELECT name
FROM random AS r1 JOIN
(SELECT (RAND() *
(SELECT MAX(id)
FROM random)) AS id)
AS r2
WHERE r1.id >= r2.id
ORDER BY r1.id ASC
LIMIT 1
รายละเอียดเพิ่มเติมhttp://jan.kneschke.de/projects/mysql/order-by-rand/
ยังไม่เห็นความแตกต่างนี้ในคำตอบ ฉันมีข้อ จำกัด เพิ่มเติมที่ฉันต้องการกำหนดเมล็ดเริ่มต้นเพื่อเลือกชุดแถวเดียวกันในแต่ละครั้ง
สำหรับ MS SQL:
ตัวอย่างขั้นต่ำ:
select top 10 percent *
from table_name
order by rand(checksum(*))
เวลาดำเนินการปกติ: 1.00
ตัวอย่าง NewId ():
select top 10 percent *
from table_name
order by newid()
เวลาดำเนินการปกติ: 1.02
NewId()
ช้ากว่าไม่มีนัยสำคัญrand(checksum(*))
ดังนั้นคุณอาจไม่ต้องการใช้กับชุดบันทึกขนาดใหญ่
การคัดเลือกด้วยเมล็ดเริ่มต้น:
declare @seed int
set @seed = Year(getdate()) * month(getdate()) /* any other initial seed here */
select top 10 percent *
from table_name
order by rand(checksum(*) % seed) /* any other math function here */
หากคุณต้องการเลือกชุดเดียวกันที่ได้รับเมล็ดดูเหมือนว่าจะทำงาน
ใน MSSQL (ทดสอบบน 11.0.5569) โดยใช้
SELECT TOP 100 * FROM employee ORDER BY CRYPT_GEN_RANDOM(10)
เร็วกว่า
SELECT TOP 100 * FROM employee ORDER BY NEWID()
ใน SQL Server คุณสามารถรวม TABLESAMPLE กับ NEWID () เพื่อรับการสุ่มที่ดีและยังมีความเร็ว สิ่งนี้มีประโยชน์อย่างยิ่งหากคุณต้องการเพียง 1 หรือจำนวนน้อย ๆ ของแถว
SELECT TOP 1 * FROM [table]
TABLESAMPLE (500 ROWS)
ORDER BY NEWID()
ด้วย SQL Server 2012+ คุณสามารถใช้ แบบสอบถาม OFFSET FETCHเพื่อทำสิ่งนี้สำหรับแถวสุ่มหนึ่งแถว
select * from MyTable ORDER BY id OFFSET n ROW FETCH NEXT 1 ROWS ONLY
โดยที่ id คือคอลัมน์ข้อมูลประจำตัวและ n คือแถวที่คุณต้องการ - คำนวณเป็นตัวเลขสุ่มระหว่าง 0 และ count () - 1 ของตาราง (offset 0 คือแถวแรกหลังจากทั้งหมด)
สิ่งนี้ใช้ได้กับรูในข้อมูลตารางตราบใดที่คุณมีดัชนีที่จะทำงานกับคำสั่งย่อย ORDER BY มันยังดีมากสำหรับการสุ่ม - ในขณะที่คุณทำงานด้วยตัวคุณเองว่าจะผ่านเข้าไป แต่ไม่มีวิธีการอื่น ๆ นอกจากนี้ประสิทธิภาพการทำงานค่อนข้างดีในชุดข้อมูลที่มีขนาดเล็กลงก็สามารถทำงานได้ดีแม้ว่าฉันจะไม่ได้ลองทดสอบประสิทธิภาพอย่างจริงจังกับหลายล้านแถว
SELECT * FROM table ORDER BY RAND() LIMIT 1
ฉันต้องเห็นด้วยกับ CD-MaN: การใช้ "ORDER BY RAND ()" จะทำงานได้ดีสำหรับโต๊ะเล็ก ๆ หรือเมื่อคุณเลือก SELECT เพียงไม่กี่ครั้ง
ฉันยังใช้เทคนิค "num_value> = RAND () * ... " และถ้าฉันต้องการผลลัพธ์แบบสุ่มฉันมีคอลัมน์ "สุ่ม" พิเศษในตารางที่ฉันอัปเดตวันละครั้ง การอัปเดตครั้งเดียวนั้นจะใช้เวลาสักครู่ (โดยเฉพาะอย่างยิ่งเพราะคุณจะต้องมีดัชนีในคอลัมน์นั้น) แต่จะเร็วกว่าการสร้างตัวเลขสุ่มสำหรับทุกแถวในแต่ละครั้งที่เลือกทำงาน
ระวังเพราะ TableSample ไม่ส่งคืนสุ่มแถวตัวอย่าง มันนำทางแบบสอบถามของคุณเพื่อดูตัวอย่างสุ่มของหน้า 8KB ที่ประกอบขึ้นเป็นแถวของคุณ จากนั้นแบบสอบถามของคุณจะถูกดำเนินการกับข้อมูลที่มีอยู่ในหน้าเหล่านี้ เนื่องจากวิธีการจัดกลุ่มข้อมูลในหน้าเหล่านี้ (ลำดับการแทรก ฯลฯ ) สิ่งนี้อาจนำไปสู่ข้อมูลที่ไม่ใช่ตัวอย่างแบบสุ่ม
ดู: http://www.mssqltips.com/tip.asp?tip=1308
หน้า MSDN นี้สำหรับ TableSample รวมถึงตัวอย่างของวิธีการสร้างตัวอย่างข้อมูลจริงแบบสุ่ม
ดูเหมือนว่าแนวคิดจำนวนมากที่แสดงยังคงใช้การสั่งซื้อ
อย่างไรก็ตามหากคุณใช้ตารางชั่วคราวคุณสามารถกำหนดดัชนีแบบสุ่ม (เช่นวิธีแก้ปัญหาที่แนะนำ) และจากนั้นคว้าตารางแรกที่มากกว่าเลขสุ่มระหว่าง 0 ถึง 1
ตัวอย่างเช่น (สำหรับ DB2):
WITH TEMP AS (
SELECT COMLUMN, RAND() AS IDX FROM TABLE)
SELECT COLUMN FROM TABLE WHERE IDX > .5
FETCH FIRST 1 ROW ONLY
วิธีที่ง่ายและมีประสิทธิภาพจากhttp://akinas.com/pages/en/blog/mysql_random_row/
SET @i = (SELECT FLOOR(RAND() * COUNT(*)) FROM table); PREPARE get_stmt FROM 'SELECT * FROM table LIMIT ?, 1'; EXECUTE get_stmt USING @i;
มีวิธีแก้ปัญหาที่ดีกว่าสำหรับ Oracle แทนที่จะใช้ dbms_random.value ในขณะที่ต้องการสแกนแบบเต็มเพื่อเรียงลำดับแถวโดย dbms_random.value และค่อนข้างช้าสำหรับตารางขนาดใหญ่
ใช้สิ่งนี้แทน:
SELECT *
FROM employee sample(1)
WHERE rownum=1
สำหรับ Firebird:
Select FIRST 1 column from table ORDER BY RAND()
สำหรับ SQL Server 2005 ขึ้นไปให้ขยาย @ GreyPanther ให้คำตอบสำหรับเคสที่num_value
ไม่มีค่าต่อเนื่อง สิ่งนี้ใช้ได้สำหรับกรณีที่เมื่อเราไม่ได้กระจายชุดข้อมูลอย่างสม่ำเสมอและเมื่อnum_value
ไม่ได้เป็นตัวเลข แต่เป็นตัวระบุที่ไม่ซ้ำกัน
WITH CTE_Table (SelRow, num_value)
AS
(
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS SelRow, num_value FROM table
)
SELECT * FROM table Where num_value = (
SELECT TOP 1 num_value FROM CTE_Table WHERE SelRow >= RAND() * (SELECT MAX(SelRow) FROM CTE_Table)
)
ฟังก์ชั่นแบบสุ่มจาก sql สามารถช่วยได้ นอกจากนี้หากคุณต้องการ จำกัด เพียงหนึ่งแถวให้เพิ่มเข้าไปในท้ายที่สุด
SELECT column FROM table
ORDER BY RAND()
LIMIT 1