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

การจัดกลุ่มข้อมูลด้วย GROUP BY และดึงค่าล่าสุดด้วย MAX() ใน MySQL

ปัญหา

เมื่อมีข้อมูลซ้ำในคอลัมน์ที่จัดกลุ่ม (เช่น 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) เพื่อประสิทธิภาพและความยืดหยุ่นดีกว่า