Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Lấy các giá trị xuất hiện nhiều nhất (Top N) trong MySQL

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

  1. Inner query: GROUP BY SubjectName + COUNT(*) + ORDER BY COUNT DESC + LIMIT 2 → lấy Top 2.
  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 ý

  • LIMIT trong subquery cần alias (AS tbl) bắt buộc trong MySQL.
  • Khi có tie (cùng count), LIMIT cắt ngang → có thể dùng ORDER 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ỳ.