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

ข้ามข้อมูลซ้ำเลือกแค่ 1 แถวต่อกลุ่มใน MySQL ด้วย GROUP BY และ MIN


แนวคิดหลัก

ใช้ GROUP BY ร่วมกับฟังก์ชัน aggregate เช่น MIN() หรือ MAX() เพื่อเลือกแค่ 1 แถวต่อกลุ่มค่าที่ซ้ำกัน

รูปแบบคำสั่ง

SELECT MIN(yourColumnName1), yourColumnName2 
FROM yourTableName 
GROUP BY yourColumnName2;

ตัวอย่างครบถ้วน

1. สร้างตาราง

mysql> create table doNotSelectDuplicateValuesDemo 
    -> ( 
    -> User_Id int NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    -> User_Name varchar(20) 
    -> ); 
Query OK, 0 rows affected (0.78 sec)

2. เพิ่มข้อมูลมีชื่อซ้ำหลายคน

mysql> insert into doNotSelectDuplicateValuesDemo(User_Name) values('John'); 
Query OK, 1 row affected (0.15 sec)
mysql> insert into doNotSelectDuplicateValuesDemo(User_Name) values('Carol'); 
Query OK, 1 row affected (0.09 sec)
mysql> insert into doNotSelectDuplicateValuesDemo(User_Name) values('Carol'); 
Query OK, 1 row affected (0.17 sec)
mysql> insert into doNotSelectDuplicateValuesDemo(User_Name) values('Carol'); 
Query OK, 1 row affected (0.08 sec)
mysql> insert into doNotSelectDuplicateValuesDemo(User_Name) values('Sam'); 
Query OK, 1 row affected (0.28 sec)
mysql> insert into doNotSelectDuplicateValuesDemo(User_Name) values('Mike'); 
Query OK, 1 row affected (0.19 sec)
mysql> insert into doNotSelectDuplicateValuesDemo(User_Name) values('Bob'); 
Query OK, 1 row affected (0.16 sec)
mysql> insert into doNotSelectDuplicateValuesDemo(User_Name) values('David'); 
Query OK, 1 row affected (0.21 sec)
mysql> insert into doNotSelectDuplicateValuesDemo(User_Name) values('Maxwell'); 
Query OK, 1 row affected (0.13 sec)
mysql> insert into doNotSelectDuplicateValuesDemo(User_Name) values('Bob'); 
Query OK, 1 row affected (0.11 sec)
mysql> insert into doNotSelectDuplicateValuesDemo(User_Name) values('Ramit'); 
Query OK, 1 row affected (0.16 sec)

3. ดูข้อมูลทั้งหมด (มีซ้ำ)

mysql> select * from doNotSelectDuplicateValuesDemo;
+---------+-----------+
| User_Id | User_Name |
+---------+-----------+
| 1       | John      |
| 2       | Carol     |
| 3       | Carol     |
| 4       | Carol     |
| 5       | Sam       |
| 6       | Mike      |
| 7       | Bob       |
| 8       | David     |
| 9       | Maxwell   |
| 10      | Bob       |
| 11      | Ramit     |
+---------+-----------+

4. Query เลือกแค่ 1 แถวต่อชื่อ (เอา User_Id ต่ำสุด)

mysql> select min(User_Id), User_Name from doNotSelectDuplicateValuesDemo group by User_Name;
+--------------+-----------+
| min(User_Id) | User_Name |
+--------------+-----------+
| 1            | John      |
| 2            | Carol     |
| 5            | Sam       |
| 6            | Mike      |
| 7            | Bob       |
| 8            | David     |
| 9            | Maxwell   |
| 11           | Ramit     |
+--------------+-----------+

วิธีเลือกแถวล่าสุดแทน (ใช้ MAX)

SELECT MAX(User_Id), User_Name 
FROM doNotSelectDuplicateValuesDemo 
GROUP BY User_Name;

MySQL 8.0+ ใช้ ROW_NUMBER() (Window Function)

WITH ranked AS (
  SELECT *, ROW_NUMBER() OVER (PARTITION BY User_Name ORDER BY User_Id) as rn
  FROM doNotSelectDuplicateValuesDemo
)
SELECT User_Id, User_Name FROM ranked WHERE rn = 1;

ข้อควรระวัง: GROUP BY แบบนี้เลือกได้แค่คอลัมน์ที่ group และ aggregate function เท่านั้น หากต้องการคอลัมน์อื่นๆ ต้องใช้ subquery หรือ window function