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

Tìm giá trị lớn thứ N (Nth highest) trong MySQL

Cách chuẩn: SELECT DISTINCT cot FROM bang ORDER BY cot DESC LIMIT (N-1), 1.

Cú pháp

SELECT DISTINCT ten_cot
FROM ten_bang
ORDER BY ten_cot DESC
LIMIT (N-1), 1;
  • DISTINCT: Loại bỏ giá trị trùng (nếu muốn distinct Nth highest).
  • LIMIT offset, count: Bỏ qua offset hàng, lấy count hàng. Offset = N-1.

Ví dụ: Tìm giá trị lớn thứ 3 (N=3)

Tạo bảng:

CREATE TABLE DemoTable1594 (Marks INT);
INSERT INTO DemoTable1594 VALUES (76), (95), (56), (96), (89);

Giá trị distinct DESC: 96, 95, 89, 76, 56.

Lớn thứ 3 = 89 (offset 2, limit 1):

SELECT DISTINCT Marks FROM DemoTable1594 ORDER BY Marks DESC LIMIT 2, 1;

Kết quả

Marks
89

Các trường hợp đặc biệt

1. Không dùng DISTINCT (lấy theo hàng, kể trùng)

SELECT Marks FROM DemoTable1594 ORDER BY Marks DESC LIMIT 2, 1;

2. MySQL 8.0+: Window Function

SELECT Marks FROM (
    SELECT DISTINCT Marks, ROW_NUMBER() OVER (ORDER BY Marks DESC) AS rn
    FROM DemoTable1594
) t WHERE rn = 3;

3. N lớn (pagination): Offset lớn chậm

Với N=100000, LIMIT 99999, 1 rất chậm. Cách tốt hơn:

-- Nếu có index trên Marks
SELECT Marks FROM DemoTable1594 WHERE Marks < (SELECT Marks FROM DemoTable1594 ORDER BY Marks DESC LIMIT 99999, 1) ORDER BY Marks DESC LIMIT 1;

Hoặc dùng keyset pagination (cần cột unique).

So sánh cách làm

Khuyên dùng: DISTINCT ... ORDER BY ... DESC LIMIT N-1, 1 cho N nhỏ; Window Function cho N lớn hoặc logic phức tạp.

CáchPhiên bảnHiệu năngXử lý tie
DISTINCT + LIMIT offset,1Tất cảTB (filesort nếu không index)Distinct values
ROW_NUMBER() OVER8.0+Tốt (có thể dùng index)Linh hoạt
Subquery MAX lồng nhauTất cảKém (N lần subquery)Distinct