Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> MySQL

การสุ่มเลือกแถวที่ไม่ซ้ำกันใน MySQL ด้วย ORDER BY RAND() และ DISTINCT

เพื่อสุ่มเลือกแถวที่ไม่ซ้ำกัน ใช้ DISTINCT ร่วมกับ ORDER BY RAND() และ LIMIT

สร้างตารางตัวอย่าง

mysql> create table DemoTable ( 
    Id int NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    Name varchar(40) ); 
Query OK, 0 rows affected (0.54 sec)

เพิ่มข้อมูลตัวอย่าง (มีค่าซ้ำ)

mysql> insert into DemoTable(Name) values('John Doe'); Query OK, 1 row affected (0.13 sec)
mysql> insert into DemoTable(Name) values('Chris Brown'); Query OK, 1 row affected (0.11 sec)
mysql> insert into DemoTable(Name) values('Adam Smith'); Query OK, 1 row affected (0.09 sec)
mysql> insert into DemoTable(Name) values('John Doe'); Query OK, 1 row affected (0.24 sec)
mysql> insert into DemoTable(Name) values('John Doe'); Query OK, 1 row affected (0.23 sec)
mysql> insert into DemoTable(Name) values('Chris Brown'); Query OK, 1 row affected (0.53 sec)
mysql> insert into DemoTable(Name) values('Adam Smith'); Query OK, 1 row affected (0.12 sec)

แสดงข้อมูลทั้งหมด

mysql> select *from DemoTable;
+----+-------------+
| Id | Name        |
+----+-------------+
|  1 | John Doe    |
|  2 | Chris Brown |
|  3 | Adam Smith  |
|  4 | John Doe    |
|  5 | John Doe    |
|  6 | Chris Brown |
|  7 | Adam Smith  |
+----+-------------+
7 rows in set (0.00 sec)

คิวรี่สุ่มเลือก 3 ชื่อที่ไม่ซ้ำกัน

mysql> select distinct Name from DemoTable order by rand() limit 3;

ผลลัพธ์ (สุ่มทุกครั้ง):

+-------------+
| Name        |
+-------------+
| Chris Brown |
| John Doe    |
| Adam Smith  |
+-------------+
3 rows in set (0.00 sec)

คำอธิบาย

  • DISTINCT - กรองค่าซ้ำออกไปก่อน
  • ORDER BY RAND() - สุ่มลำดับแถว
  • LIMIT 3 - จำกัด 3 แถว

ประสิทธิภาพและข้อควรระวัง

  • ORDER BY RAND() ช้ามากในตารางใหญ่ (Full table scan + filesort)
  • วิธีที่เร็วกว่าสำหรับตารางใหญ่:
    • สุ่ม ID แล้ว JOIN: SELECT * FROM table WHERE id >= (SELECT FLOOR(RAND() * (MAX(id)-MIN(id)+1)) + MIN(id)) LIMIT 1
    • หรือใช้ TABLESAMPLE (MySQL 8.0.23+)
  • ใช้ DISTINCT ก่อน ORDER BY RAND() เพื่อลดจำนวนแถวที่ต้องสุ่ม