ปัญหา
เมื่อมีข้อมูลซ้ำในคอลัมน์ที่จัดกลุ่ม (เช่น User เดียวมีหลายแถว) และต้องการดึงเฉพาะแถวที่มีค่าล่าสุด (Latest) ตามคอลัมน์วันที่/เวลา
วิธีแก้: ใช้ GROUP BY ร่วมกับ MAX()
SELECT UserName, UserEmailId, MAX(UserLastPost)
FROM DemoTable621
GROUP BY UserName, UserEmailId;
ตัวอย่างสมบูรณ์
1. สร้างตารางและข้อมูลทดสอบ
CREATE TABLE DemoTable621 (
UserName VARCHAR(100),
UserEmailId VARCHAR(100),
UserLastPost DATETIME
);
INSERT INTO DemoTable621 VALUES ('John', 'John@gmail.com', '2019-04-10 11:01:10');
INSERT INTO DemoTable621 VALUES ('John', 'John@gmail.com', '2019-07-14 13:07:10');
2. ข้อมูลก่อนจัดกลุ่ม
+----------+----------------+---------------------+
| UserName | UserEmailId | UserLastPost |
+----------+----------------+---------------------+
| John | John@gmail.com | 2019-04-10 11:01:10 |
| John | John@gmail.com | 2019-07-14 13:07:10 |
+----------+----------------+---------------------+
3. Query ดึงเฉพาะล่าสุด
SELECT UserName, UserEmailId, MAX(UserLastPost) AS LastPost
FROM DemoTable621
GROUP BY UserName, UserEmailId;
4. ผลลัพธ์
+----------+----------------+---------------------+
| UserName | UserEmailId | LastPost |
+----------+----------------+---------------------+
| John | John@gmail.com | 2019-07-14 13:07:10 |
+----------+----------------+---------------------+
เทคนิคขั้นสูง: ดึงคอลัมน์อื่นของแถวที่ MAX
หากต้องการคอลัมน์อื่นของแถวที่มีวันที่มากที่สุด ใช้ Subquery หรือ JOIN:
วิธี 1: Subquery (Correlated)
SELECT t1.*
FROM DemoTable621 t1
JOIN (
SELECT UserName, UserEmailId, MAX(UserLastPost) AS MaxDate
FROM DemoTable621
GROUP BY UserName, UserEmailId
) t2 ON t1.UserName = t2.UserName
AND t1.UserEmailId = t2.UserEmailId
AND t1.UserLastPost = t2.MaxDate;
วิธี 2: ROW_NUMBER() (MySQL 8.0+)
WITH Ranked AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY UserName, UserEmailId ORDER BY UserLastPost DESC) AS rn
FROM DemoTable621
)
SELECT UserName, UserEmailId, UserLastPost
FROM Ranked
WHERE rn = 1;
สรุป
- ใช้
MAX(date_column)ร่วมGROUP BYสำหรับดึงค่าล่าสุดแบบง่าย - ต้อง GROUP BY ทุกคอลัมน์ที่ไม่ใช่ Aggregate Function
- MySQL 8.0+ ควรใช้ Window Function (
ROW_NUMBER) เพื่อประสิทธิภาพและความยืดหยุ่นดีกว่า