การสร้างคอลัมน์ค่าสุ่มชั่วคราวเพื่อเรียงลำดับสุ่ม
ใช้ Subquery สร้างคอลัมน์ RAND() + 1 (ค่า 1.0 - 2.0) แล้ว ORDER BY RandomRecord DESC เพื่อเรียงสุ่ม ทำได้ใน Query เดียวโดยไม่ต้อง ALTER TABLE
ตัวอย่างการใช้งาน
สร้างตารางและเพิ่มข้อมูล:
mysql> CREATE TABLE DemoTable (
-> StudentId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> StudentName VARCHAR(20)
-> );
Query OK, 0 rows affected (0.57 sec)
mysql> INSERT INTO DemoTable(StudentName) VALUES('Larry'),('Sam'),('Mike'),('Carol'),('Robert'),('Chris');
Query OK, 6 rows affected (0.15 sec)
ข้อมูลตามลำดับ Id:
mysql> SELECT * FROM DemoTable;
+-----------+-------------+
| StudentId | StudentName |
+-----------+-------------+
| 1 | Larry |
| 2 | Sam |
| 3 | Mike |
| 4 | Carol |
| 5 | Robert |
| 6 | Chris |
+-----------+-------------+
6 rows in set (0.00 sec)
สร้างคอลัมน์สุ่มและเรียง DESC:
mysql> SELECT * FROM (
-> SELECT StudentName, RAND() + 1 AS RandomRecord FROM DemoTable
-> ) AS tbl
-> ORDER BY RandomRecord DESC;
+-------------+--------------------+
| StudentName | RandomRecord |
+-------------+--------------------+
| Carol | 1.8973721451101566 |
| Chris | 1.7821308670399065 |
| Mike | 1.4640037673190271 |
| Larry | 1.4134691557041081 |
| Sam | 1.1408822407395414 |
| Robert | 1.0948494543273461 |
+-------------+--------------------+
6 rows in set (0.00 sec)
คำอธิบาย
RAND()คืนค่า Float 0.0 - 1.0 (ไม่รวม 1)RAND() + 1ทำให้ช่วง 1.0 - 2.0 (กันไม่ให้เป็น 0)- Subquery (Derived Table) ต้องมี Alias (
AS tbl) - ORDER BY RandomRecord DESC → ค่า RAND สูงสุดอยู่บน
วิธีอื่น: ORDER BY RAND() โดยตรง
SELECT * FROM DemoTable ORDER BY RAND() LIMIT 10;
ง่ายกว่า แต่效能一样 (Full Scan + Sort) ใช้ได้กับตารางเล็ก
ข้อควรระวังประสิทธิภาพ
ORDER BY RAND() ช้ามากสำหรับตารางใหญ่ (O(N log N) Sort + No Index)
วิธีเร็วกว่าสำหรับ Random Sampling:
- WHERE RAND() < 0.01 (Bernoulli Sampling) ~1% rows, ไม่ต้อง Sort
- Offset แบบสุ่ม:
SELECT * FROM t WHERE Id >= (SELECT FLOOR(RAND() * (SELECT MAX(Id) FROM t))) ORDER BY Id LIMIT 10; - Pre-computed Random Column: เพิ่ม Col
rand_sort INT, Update บ้างครั้ง, Index บนมัน,ORDER BY rand_sort LIMIT 10