การเลือกค่า Distinct จากคอลัมน์เดียวด้วย MAX() และ GROUP BY
ใน MySQL หากต้องการเลือกค่าที่ไม่ซ้ำจากคอลัมน์หนึ่ง (เช่น StudentId) แต่ต้องการดึงคอลัมน์อื่นมาด้วย (เช่น StudentName) ไม่สามารถใช้ SELECT DISTINCT StudentId, StudentName ได้โดยตรง เพราะจะได้คู่ที่ไม่ซ้ำทั้งคู่ วิธีแก้คือใช้ฟังก์ชันรวม (Aggregate) เช่น MAX() หรือ MIN() ร่วมกับ GROUP BY
ตัวอย่างการใช้งาน
สร้างตารางและเพิ่มข้อมูลที่ StudentId ซ้ำ แต่ชื่อต่างกัน:
mysql> CREATE TABLE distinctFromOneColumn (
-> StudentId INT,
-> StudentName VARCHAR(100)
-> );
Query OK, 0 rows affected (0.77 sec)
mysql> INSERT INTO distinctFromOneColumn VALUES(1001, 'John');
Query OK, 1 row affected (0.15 sec)
mysql> INSERT INTO distinctFromOneColumn VALUES(1002, 'Carol');
Query OK, 1 row affected (0.15 sec)
mysql> INSERT INTO distinctFromOneColumn VALUES(1001, 'Sam');
Query OK, 1 row affected (0.15 sec)
mysql> INSERT INTO distinctFromOneColumn VALUES(1001, 'David');
Query OK, 1 row affected (0.16 sec)
mysql> INSERT INTO distinctFromOneColumn VALUES(1002, 'Ramit');
Query OK, 1 row affected (0.15 sec)
mysql> INSERT INTO distinctFromOneColumn VALUES(1003, 'Bob');
Query OK, 1 row affected (0.21 sec)
ข้อมูลทั้งหมด:
mysql> SELECT * FROM distinctFromOneColumn;
+-----------+-------------+
| StudentId | StudentName |
+-----------+-------------+
| 1001 | John |
| 1002 | Carol |
| 1001 | Sam |
| 1001 | David |
| 1002 | Ramit |
| 1003 | Bob |
+-----------+-------------+
6 rows in set (0.00 sec)
เลือก StudentId ที่ไม่ซ้ำ พร้อมชื่อหนึ่งชื่อ (ใช้ MAX):
mysql> SELECT StudentId, MAX(StudentName) AS StudentName
-> FROM distinctFromOneColumn
-> GROUP BY StudentId;
ผลลัพธ์ (ชื่อที่มากที่สุดตามตัวอักษร):
+-----------+-------------+
| StudentId | StudentName |
+-----------+-------------+
| 1001 | Sam |
| 1002 | Ramit |
| 1003 | Bob |
+-----------+-------------+
3 rows in set (0.00 sec)
คำอธิบายและทางเลือกอื่น
MAX(StudentName)เลือกชื่อที่มากที่สุดตามลำดับตัวอักษร (Sam > John > David)- ใช้
MIN(StudentName)จะได้ชื่อน้อยที่สุด (David, Carol, Bob) - MySQL 8.0+ สามารถใช้
ANY_VALUE(StudentName)ได้ ซึ่งเร็วกว่าและไม่ต้องเรียงลำดับ - หากต้องการชื่อแรกที่เจอ (ตามลำดับ INSERT) ให้ใช้
ROW_NUMBER()Window Function
สรุป: ใช้ GROUP BY คอลัมน์ที่ต้องการ Distinct + ฟังก์ชันรวม (MAX/MIN/ANY_VALUE) สำหรับคอลัมน์อื่น