Truy xuất bản ghi có giá trị lớn nhất (MAX) kèm cột liên quan trong MySQL
Để lấy cột khác (ví dụ: ImagePath) của hàng có giá trị tối đa (UpvoteValue), dùng Subquery với MAX() trong mệnh đề WHERE ... IN hoặc JOIN.
Ví dụ minh họa
Tạo bảng DemoTable:
mysql> CREATE TABLE DemoTable (
Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ImagePath VARCHAR(100),
UpvoteValue INT
);
Query OK, 0 rows affected (0.72 sec)
Chèn dữ liệu:
mysql> INSERT INTO DemoTable(ImagePath,UpvoteValue) VALUES('Image1.jpeg',90);
Query OK, 1 row affected (0.23 sec)
mysql> INSERT INTO DemoTable(ImagePath,UpvoteValue) VALUES('Image2.jpeg',10);
Query OK, 1 row affected (0.21 sec)
mysql> INSERT INTO DemoTable(ImagePath,UpvoteValue) VALUES('Image3.jpeg',120);
Query OK, 1 row affected (0.25 sec)
mysql> INSERT INTO DemoTable(ImagePath,UpvoteValue) VALUES('Image4.jpeg',114);
Query OK, 1 row affected (1.17 sec)
Xem dữ liệu:
mysql> SELECT * FROM DemoTable;
+----+-------------+-------------+ | Id | ImagePath | UpvoteValue | +----+-------------+-------------+ | 1 | Image1.jpeg | 90 | | 2 | Image2.jpeg | 10 | | 3 | Image3.jpeg | 120 | | 4 | Image4.jpeg | 114 | +----+-------------+-------------+ 4 rows in set (0.00 sec)
Lấy ImagePath có UpvoteValue lớn nhất:
mysql> SELECT ImagePath FROM DemoTable WHERE UpvoteValue IN (SELECT MAX(UpvoteValue) FROM DemoTable);
Kết quả:
+-------------+ | ImagePath | +-------------+ | Image3.jpeg | +-------------+ 1 row in set (0.00 sec)
Các phương pháp thay thế (hiệu suất tốt hơn)
1. ORDER BY ... LIMIT 1 (Đơn giản, nhanh)
SELECT ImagePath FROM DemoTable ORDER BY UpvoteValue DESC LIMIT 1;
2. JOIN với Subquery (Chuẩn SQL, dễ mở rộng)
SELECT d.ImagePath FROM DemoTable d JOIN (SELECT MAX(UpvoteValue) AS max_upvote FROM DemoTable) m ON d.UpvoteValue = m.max_upvote;
3. Window Function (MySQL 8.0+) - Lấy top N, xử lý tie
WITH ranked AS (
SELECT ImagePath, UpvoteValue,
RANK() OVER (ORDER BY UpvoteValue DESC) AS rnk
FROM DemoTable
)
SELECT ImagePath FROM ranked WHERE rnk = 1;
So sánh
| Phương pháp | Ưu điểm | Nhược điểm |
|---|---|---|
WHERE ... IN (SELECT MAX...) | Dễ hiểu | Subquery có thể chậm, không dùng index tốt |
ORDER BY DESC LIMIT 1 | Nhanh, đơn giản | Chỉ lấy 1 hàng (nếu tie thì lấy tùy ý) |
JOIN (SELECT MAX...) | Chuẩn, lấy được tất cả hàng tie | Hơi dài |
RANK() OVER | Xử lý tie tốt, top N dễ dàng | Chỉ MySQL 8.0+ |
Lưu ý
- Nếu có nhiều bản ghi cùng MAX upvote →
INvàJOINtrả về tất cả,LIMIT 1chỉ trả 1 - Nên tạo index trên
UpvoteValueđể tối ưuMAX()vàORDER BY