Giới thiệu
Sử dụng ORDER BY ... DESC LIMIT 1 OFFSET n để lấy lương cao nhất thứ n+1. Kết hợp DISTINCT để loại bỏ giá trị trùng lặp.
Ví dụ thực hành
1. Tạo bảng DemoTable867
mysql> CREATE TABLE DemoTable867 (EmployeeSalary INT);
2. Chèn 6 mức lương
mysql> INSERT INTO DemoTable867 VALUES (63737),(899833),(23644),(89393),(534333),(889322);
3. Lương cao nhất (1st)
mysql> SELECT DISTINCT EmployeeSalary FROM DemoTable867 ORDER BY EmployeeSalary DESC LIMIT 1;
-- 899833
4. Lương cao nhì (2nd)
mysql> SELECT DISTINCT EmployeeSalary FROM DemoTable867 ORDER BY EmployeeSalary DESC LIMIT 1 OFFSET 1;
-- 889322
5. Lương cao ba (3rd)
mysql> SELECT DISTINCT EmployeeSalary FROM DemoTable867 ORDER BY EmployeeSalary DESC LIMIT 1 OFFSET 2;
-- 534333
Cách hiện đại (MySQL 8.0+): Window Function
SELECT DISTINCT EmployeeSalary
FROM (
SELECT EmployeeSalary,
DENSE_RANK() OVER (ORDER BY EmployeeSalary DESC) AS rnk
FROM DemoTable867
) t
WHERE rnk <= 3
ORDER BY EmployeeSalary DESC;
DENSE_RANK(): Xếp hạng dày đặc (1,2,2,3...).RANK()có gap (1,2,2,4...).- Dễ mở rộng lấy top N, top N per department (
PARTITION BY dept).
Cách cũ (Subquery) - tương thích mọi phiên bản
-- Top 3 distinct salary
SELECT DISTINCT EmployeeSalary FROM DemoTable867
ORDER BY EmployeeSalary DESC LIMIT 3;
Đơn giản, hiệu quả cho top N nhỏ.
Lưu ý
DISTINCTquan trọng: nếu nhiều nhân viên cùng lương, chỉ đếm 1 lần.- Index trên
EmployeeSalarygiúpORDER BY ... LIMITrất nhanh (chỉ đọc N hàng). OFFSETlớn chậm → dùng keyset pagination nếu cần phân trang sâu.- Cột lương nên dùng
DECIMAL(12,2)thay vì INT cho tiền tệ thực tế.