Bài toán
Tìm Top N giá trị xuất hiện nhiều nhất trong cột có dữ liệu trùng lặp.
Ví dụ
Bảng DemoTable610 chứa SubjectName với nhiều giá trị trùng:
CREATE TABLE DemoTable610 (SubjectName VARCHAR(100));
INSERT INTO DemoTable610 VALUES
('MySQL'), ('Java'), ('MySQL'), ('MongoDB'), ('MySQL'), ('MySQL'),
('Java'), ('MongoDB'), ('C'), ('C++'), ('MongoDB'), ('MySQL'),
('Java'), ('Python'), ('MySQL');
Thống kê: MySQL (7), Java (3), MongoDB (3), C (1), C++ (1), Python (1).
Truy vấn Top 2
SELECT SubjectName
FROM (
SELECT SubjectName
FROM DemoTable610
GROUP BY SubjectName
ORDER BY COUNT(SubjectName) DESC
LIMIT 2
) AS tbl
ORDER BY SubjectName;
Kết quả (sắp xếp alphabet cho đẹp):
+-------------+
| SubjectName |
+-------------+
| Java |
| MySQL |
+-------------+
Giải thích
- Inner query:
GROUP BY SubjectName+COUNT(*)+ORDER BY COUNT DESC+LIMIT 2→ lấy Top 2. - Outer query:
ORDER BY SubjectNameđể sắp xếp alphabet kết quả cuối.
Mở rộng: Lấy cả số lượng
SELECT SubjectName, cnt
FROM (
SELECT SubjectName, COUNT(*) AS cnt
FROM DemoTable610
GROUP BY SubjectName
ORDER BY cnt DESC, SubjectName
LIMIT 2
) AS t;
MySQL 8.0: Window Function
SELECT SubjectName, cnt
FROM (
SELECT SubjectName, COUNT(*) AS cnt,
ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC) AS rn
FROM DemoTable610
GROUP BY SubjectName
) AS t
WHERE rn <= 2;
Lưu ý
LIMITtrong subquery cần alias (AS tbl) bắt buộc trong MySQL.- Khi có tie (cùng count),
LIMITcắt ngang → có thể dùngORDER BY cnt DESC, SubjectNameđể deterministic. - Với dữ liệu lớn, cân nhắc materialized view hoặc summary table cập nhật định kỳ.