Chuyển đến nội dung chính

SQL RANK(): Cách sắp xếp các hàng với ví dụ minh họa

Tìm hiểu cách dùng hàm SQL RANK() để gán thứ hạng cho các hàng, xử lý đồng hạng và so sánh với DENSE_RANK() và ROW_NUMBER().
Đã cập nhật 4 thg 5, 2026  · 6 phút đọc

Khi làm việc với SQL, việc sắp xếp dữ liệu khá đơn giản vì bạn có thể dễ dàng dùng ORDER BY để sắp xếp các hàng. Tuy nhiên, chỉ sắp xếp kết quả thì không cho bạn biết vị trí của từng hàng trong thứ tự đó. Đây là lúc xếp hạng trở nên hữu ích. Thay vì chỉ xem dữ liệu đã sắp, bạn có thể muốn gán vị trí như 1, 2, hoặc 3 cho mỗi hàng dựa trên tiêu chí cụ thể.

Hàm RANK() giải quyết vấn đề này bằng cách gán một thứ hạng dạng số cho mỗi hàng theo thứ tự đã xác định. RANK() là một phần của các hàm cửa sổ (window functions) trong SQL, cho phép bạn thực hiện tính toán trên một tập các hàng nhưng vẫn trả về kết quả cho từng hàng riêng lẻ. 

Trong hướng dẫn này, tôi sẽ giới thiệu cú pháp của RANK(), các ví dụ thực tế, cách hàm xử lý đồng hạng, và so sánh với các hàm tương tự như DENSE_RANK()ROW_NUMBER().

Nếu bạn mới học SQL, hãy bắt đầu với khóa học Giới thiệu về SQL, hoặc khóa SQL Trung cấp nếu bạn đã có chút kinh nghiệm. 

SQL RANK() là gì?

Hàm SQL RANK() là một hàm cửa sổ gán thứ hạng cho mỗi hàng dựa trên một thứ tự xác định. Xếp hạng hoàn toàn do ORDER BY bên trong hàm cửa sổ quyết định. Do đó, nó gán cho mỗi hàng một vị trí như 1, 2, 3, v.v., theo mệnh đề ORDER BY.

Bạn cần lưu ý rằng khi dùng RANK():

  • Các hàng có cùng giá trị (đồng hạng) sẽ nhận cùng một thứ hạng.
  • Khi có đồng hạng, dãy xếp hạng sẽ xuất hiện khoảng trống. Ví dụ, nếu hai hàng cùng hạng 2, thì hạng tiếp theo sẽ là 4 chứ không phải 3.

Cú pháp SQL RANK()

Cú pháp cơ bản của hàm RANK() là:

RANK() OVER (ORDER BY column)

Trong đó:

  • OVER: Xác định cửa sổ (tập các hàng) mà hàm sẽ hoạt động.

  • ORDER BY: Quy định cách áp dụng xếp hạng, chẳng hạn từ cao xuống thấp.

  • PARTITION BY (tùy chọn): Chia dữ liệu thành các nhóm, xếp hạng riêng trong từng nhóm.

Dưới đây là cú pháp của hàm RANK() với mệnh đề PARTITION BY:

RANK() OVER (PARTITION BY column1 ORDER BY column2)

Hàm SQL RANK() được hỗ trợ rộng rãi trên các hệ quản trị cơ sở dữ liệu lớn, bao gồm PostgreSQL, MySQL (8.0+), Microsoft SQL Server và Oracle Database. Cú pháp nhìn chung nhất quán giữa các hệ này vì nó là một phần của tiêu chuẩn ANSI SQL.

Ví dụ cơ bản về SQL RANK()

Giờ bạn đã nắm cú pháp của RANK(), hãy xem một ví dụ đơn giản về cách nó hoạt động.

Giả sử bạn có bảng employees với thông tin lương của từng nhân viên.

Bảng nhân viên.

Bạn có thể dùng truy vấn sau để xếp hạng nhân viên theo mức lương.

-- Rank employees by salary
SELECT 
    name,
    salary,
    RANK() OVER (ORDER BY salary DESC) AS rank_position
FROM employees;

Trong truy vấn trên, các hàng được sắp theo lương từ cao xuống thấp, nên mức lương cao nhất nhận hạng 1. Khi hai hàng có cùng mức lương, chúng nhận cùng một thứ hạng.

Sử dụng hàm RANK() trong SQL.

Bạn sẽ thấy rằng nếu hai hàng có cùng giá trị, chúng sẽ nhận cùng hạng.

Sau đó hạng tiếp theo sẽ bị bỏ qua. SQL tính đến trường hợp đồng hạng bằng cách bỏ qua giá trị hạng kế tiếp.

Tôi khuyến nghị bạn học khóa Giới thiệu về SQL Server để tìm hiểu thêm về nhóm dữ liệu và tổng hợp dữ liệu.

SQL RANK() với PARTITION BY

Như đã đề cập, mệnh đề PARTITION BY cho phép bạn áp dụng xếp hạng trong từng nhóm thay vì trên toàn bộ tập dữ liệu.

Trong ví dụ dưới đây, nhân viên được nhóm theo department, và việc xếp hạng bắt đầu lại trong mỗi phòng ban. Do đó, mỗi nhóm có dãy xếp hạng độc lập của riêng mình.

-- Rank employees within each department
SELECT 
    name,
    department,
    salary,
    RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank
FROM employees;

Sử dụng SQL RANK() với PARTITION BY

Từ kết quả trên, ta thấy ở “Sales”, cả Emily Johnson và Michael Brown cùng hạng 1, trong khi ở “HR”, William Miller và Olivia Wilson cũng cùng hạng 1.

SQL RANK() so với DENSE_RANK() và ROW_NUMBER()

Khi xếp hạng dữ liệu trong SQL, bạn có thể chọn dùng RANK(), DENSE_RANK() hoặc ROW_NUMBER(). Các hàm này trông giống nhau nhưng hành vi như sau:

  • RANK(): Đồng hạng sẽ cùng thứ hạng, do đó xuất hiện khoảng trống sau đồng hạng.

  • DENSE_RANK(): Đồng hạng sẽ cùng thứ hạng, không có khoảng trống trong dãy.

  • ROW_NUMBER(): Mỗi hàng nhận một số duy nhất, không có đồng hạng, ngay cả khi giá trị bằng nhau.

Để hiểu rõ hơn sự khác biệt, hãy so sánh song song bằng truy vấn dưới đây:

-- Compare RANK() vs DENSE_RANK() vs ROW_NUMBER()
SELECT 
    name,
    salary,

    RANK() OVER (ORDER BY salary DESC) AS rank_val,          -- allows gaps after ties

    DENSE_RANK() OVER (ORDER BY salary DESC) AS dense_rank1,  -- no gaps, consecutive ranks

    ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num      -- always unique sequence

FROM employees;

SQL RANK() so với DENSE_RANK() và ROW_NUMBER()

Từ các kết quả trên, bạn có thể lựa chọn:

  • Dùng RANK() khi vị trí có ý nghĩa và chấp nhận có khoảng trống.

  • Dùng DENSE_RANK() khi bạn muốn dãy xếp hạng liên tục.

  • Dùng ROW_NUMBER() khi mỗi hàng phải có số thứ tự duy nhất, ví dụ trong phân trang dữ liệu.

Khi nào nên dùng SQL RANK()

Hàm RANK() đặc biệt hữu ích khi bạn muốn sắp xếp dữ liệu đồng thời xử lý đồng hạng một cách tự nhiên. Tôi cũng thấy nó quan trọng trong các trường hợp sau:

  • Bảng xếp hạng: Khi bạn muốn xếp hạng người chơi hoặc người dùng dựa trên điểm số, cho phép đồng hạng khi hiệu suất bằng nhau.
  • Xếp hạng hiệu suất bán hàng: nếu bạn muốn xác định nhân viên hoặc khu vực có hiệu suất cao theo doanh thu, ngay cả khi kết quả bằng nhau.
  • Xác định Top-N giá trị: Hữu ích cho các truy vấn như “top 3 mức lương”, đặc biệt khi cần bao gồm trường hợp đồng hạng.

Lỗi thường gặp với SQL RANK()

Dưới đây là một số lỗi tôi từng gặp khi dùng hàm SQL RANK() và cách bạn có thể tránh:

  • Quên ORDER BY: Thiếu mệnh đề ORDER BY sẽ khiến xếp hạng không có logic xác định và có thể trả về kết quả ngoài mong đợi.

  • Hiểu sai hành vi đồng hạng: Là người mới, bạn có thể kỳ vọng 1, 2, 2, 3, nhưng RANK() tạo khoảng trống (1, 2, 2, 4) trong thứ hạng.

  • Dùng RANK() khi cần ROW_NUMBER(): Nếu bạn cần dãy số tuần tự duy nhất, ROW_NUMBER() là lựa chọn phù hợp hơn.

  • Không dùng PARTITION BY khi cần: Nếu không phân vùng, việc xếp hạng sẽ áp dụng trên toàn cục thay vì trong từng nhóm.

Thực hành tốt khi dùng SQL RANK()

Để giữ cho truy vấn gọn gàng và đảm bảo kết quả như mong đợi, tôi khuyên bạn nên tuân theo các thực hành tốt sau khi dùng hàm SQL RANK():

  • Luôn xác định thứ tự rõ ràng: Chỉ rõ mệnh đề ORDER BY, như DESC, để tránh xếp hạng mơ hồ.

  • Chọn hàm xếp hạng phù hợp: Dùng RANK(), DENSE_RANK() hoặc ROW_NUMBER() tùy theo cách bạn muốn xử lý đồng hạng.

  • Kiểm thử kịch bản đồng hạng: Trước khi đưa vào sản xuất, hãy kiểm tra hành vi dữ liệu khi có giá trị trùng lặp.

  • Kết hợp với lọc dữ liệu: Vì bạn không thể dùng RANK() trực tiếp trong mệnh đề WHERE, bạn cần bao truy vấn xếp hạng trong một Truy vấn lồng hoặc CTE khi bạn muốn lọc “Top N”.

Kết luận

RANK() là công cụ hữu ích để so sánh có thứ tự trong SQL, đặc biệt khi bạn cần kết quả phản ánh các tình huống thực tế như giá trị bằng nhau. Hiểu cách nó xử lý đồng hạng và vì sao thứ hạng có thể lặp lại và bỏ qua số là rất quan trọng để phân tích chính xác. Khi nắm vững hành vi này, bạn sẽ biết khi nào nên chọn nó cùng với các lựa chọn thay thế như DENSE_RANK()ROW_NUMBER(), tùy theo trường hợp sử dụng cụ thể.

Giờ đây bạn đã biết cách xếp hạng dữ liệu trong SQL, tôi khuyến nghị bạn xem lộ trình nghề nghiệp Associate Data Analyst in SQL nếu bạn quan tâm trở thành một nhà phân tích dữ liệu thành thạo để học các kỹ năng cần thiết. Khóa Lập báo cáo trong SQL cũng phù hợp nếu bạn muốn học cách xây dựng dashboard chuyên nghiệp bằng SQL.


Allan Ouko's photo
Author
Allan Ouko
LinkedIn
Biên tập viên kỹ thuật về Khoa học dữ liệu với kinh nghiệm thực tế trong phân tích dữ liệu, trí tuệ doanh nghiệp và khoa học dữ liệu. Tôi viết nội dung thực tiễn, tập trung vào ngành về SQL, Python, Power BI, Databricks và kỹ thuật dữ liệu, dựa trên công việc phân tích trong thế giới thực. Bài viết của tôi kết nối chiều sâu kỹ thuật với tác động kinh doanh, giúp các chuyên gia chuyển đổi dữ liệu thành những quyết định vững chắc.

Câu hỏi thường gặp về SQL RANK()

RANK() khác gì so với ORDER BY?

ORDER BY chỉ sắp xếp các hàng, còn RANK() gán vị trí dạng số cho từng hàng sau khi sắp xếp.

Tại sao có khoảng trống trong kết quả RANK()?

Xuất hiện khoảng trống trong kết quả RANK() vì nhiều hàng chia sẻ cùng thứ hạng khi đồng hạng, đẩy hạng kế tiếp tăng lên.

Sự khác nhau giữa RANK() và DENSE_RANK() là gì?

RANK() tạo khoảng trống sau đồng hạng, còn DENSE_RANK() gán thứ hạng liên tiếp không có khoảng trống.

Sự khác nhau giữa RANK() và ROW_NUMBER() là gì?

RANK() cho phép đồng hạng, còn ROW_NUMBER() gán số duy nhất cho mọi hàng bất kể trùng lặp.

RANK() có được hỗ trợ trong tất cả cơ sở dữ liệu không?

Hầu hết các cơ sở dữ liệu hiện đại đều hỗ trợ RANK(), bao gồm PostgreSQL, MySQL (8.0+), Microsoft SQL Server và Oracle Database.

Chủ đề

Học SQL với DataCamp

Courses

Xử lý dữ liệu trong SQL

4 giờ
319.8K
Xem chi tiếtRight Arrow
Bắt đầu khóa học
Xem thêmRight Arrow
Có liên quan

blogs

Claude Opus 4.6: Tính năng, điểm chuẩn, các bài kiểm tra thực hành và hơn thế nữa

Mô hình mới nhất của Anthropic dẫn đầu bảng xếp hạng về mã hóa theo hướng tác nhân và suy luận phức tạp. Thêm nữa, nó có cửa sổ ngữ cảnh 1M.
Matt Crabtree's photo

Matt Crabtree

10 phút

Xem thêmXem thêm