Sau những bài viết khởi động làm quen với SQL, ở bài viết lần này, mình sẽ giới thiệu cho các bạn về cách sử dụng công cụ Sort để sắp xếp kết quả truy vấn.
Theo thứ tự logic của xử lý truy vấn, ORDER BY là giai đoạn cuối cùng của một câu lệnh SELECT được thực thi. ORDER BY cho phép bạn kiểm soát việc sắp xếp các hàng khi chúng được trả về từ SQL Server đến ứng dụng khách hàng. Trong bài viết này, mình sẽ chia sẻ tới các bạn một vài cách để điều chỉnh cách mà kết quả truy vấn hiển thị, bao gồm sắp xếp, giới hạn số lượng kết quả và cả phân trang kết quả.
Các nội dung chính
Sử dụng mệnh đề ORDER BY
Để yêu cầu SQL Server trả về kết quả truy vấn của bạn theo một thứ tự cụ thể, bạn thêm mệnh đề ORDER BY trong biểu mẫu sau:
SELECT <select_list>
FROM <table_source>
ORDER BY <order_by_list> [ASC|DESC];
ORDER BY có thể lấy một số loại phần tử trong danh sách của nó:
- Các cột theo tên. Bạn có thể chỉ định tên của (các) cột mà kết quả sẽ được sắp xếp. Kết quả được trả về theo thứ tự của cột đầu tiên, sau đó được sắp xếp theo từng cột bổ sung theo thứ tự.
- Bí danh cột (alias). Vì ORDER BY được xử lý sau mệnh đề SELECT, nó có quyền truy cập vào các bí danh được xác định trong danh sách SELECT.
- Các cột theo vị trí thứ tự trong danh sách SELECT. Sử dụng vị trí không được khuyến khích trong các ứng dụng của bạn, vì như vậy sẽ khó đọc hơn và cần phải cẩn thận hơn để giữ cho danh sách ORDER BY được cập nhật. Tuy nhiên, đối với các biểu thức phức tạp trong danh sách SELECT, việc sử dụng số vị trí có thể hữu ích trong quá trình khắc phục sự cố.
- Các cột không có trong danh sách SELECT, nhưng có sẵn từ các bảng được liệt kê trong mệnh đề FROM. Nếu truy vấn sử dụng tùy chọn DISTINCT, bất kỳ cột nào trong danh sách ORDER BY phải được đưa vào danh sách SELECT.
Ngoài việc chỉ định cột nào nên được sử dụng để xác định thứ tự sắp xếp, bạn cũng có thể kiểm soát hướng sắp xếp. Bạn có thể sử dụng ASC để tăng dần (A-Z, 0-9) hoặc DESC để giảm dần (Z-A, 9-0). Sắp xếp tăng dần là mặc định. Mỗi cột có thể có hướng riêng được chỉ định, như trong ví dụ sau, bạn sắp xếp cột theo thứ tự Category tăng dần (A-Z) và Price (giá) giảm dần (9-0):
SELECT ProductCategoryID AS Category, ProductName
FROM Production.Product
ORDER BY Category ASC, Price DESC;
Giới hạn kết quả được sắp xếp (Limiting sorted results)
Sử dụng mệnh đề TOP
Cú pháp đơn giản của mệnh đề TOP, được sử dụng với ORDER BY, như sau:
SELECT TOP (N) <column_list>
FROM <table_source>
WHERE <search_condition>
ORDER BY <order list>;
Ví dụ: để chỉ truy xuất 10 sản phẩm đắt nhất từ bảng Production.Product, bạn sử dụng truy vấn sau:
SELECT TOP 10 Name, ListPrice
FROM Production.Product
ORDER BY ListPrice DESC;
Kết quả có thể giống như sau:

Toán tử TOP phụ thuộc vào mệnh đề ORDER BY để cung cấp mức độ ưu tiên có ý nghĩa cho các hàng được chọn. TOP có thể được sử dụng mà không có ORDER BY, nhưng trong trường hợp đó, bạn sẽ không có cách nào để dự đoán hàng nào sẽ được trả về. Trong ví dụ này, 10 đơn đặt hàng bất kỳ có thể bị trả lại nếu không có ORDER BY.
Sử dụng WITH TIES
Ngoài việc chỉ định một số lượng hàng cố định sẽ được trả lại, từ khóa TOP cũng chấp nhận tùy chọn WITH TIES, tùy chọn này sẽ truy xuất bất kỳ hàng nào có giá trị có thể được tìm thấy trong N hàng trên cùng đã chọn.
Trong ví dụ trước, truy vấn trả về 10 sản phẩm đầu tiên theo thứ tự giá giảm dần. Tuy nhiên, bằng cách thêm tùy chọn WITH TIES vào mệnh đề TOP, bạn sẽ thấy rằng nhiều hàng hơn đủ điều kiện để đưa vào top 10 sản phẩm đắt nhất:
SELECT TOP 10 WITH TIES Name, ListPrice
FROM Production.Product
ORDER BY ListPrice DESC;
Sử dụng PERCENT
Để trả về phần trăm các hàng đủ điều kiện, hãy sử dụng tùy chọn PERCENT với TOP thay vì một số cố định.
SELECT TOP 10 PERCENT Name, ListPrice
FROM SalesLT.Product
ORDER BY ListPrice DESC;
PERCENT cũng có thể được sử dụng với tùy chọn WITH TIES.
Lưu ý: Với mục đích đếm hàng, TOP (N) PERCENT sẽ làm tròn đến số nguyên gần nhất.
Phân trang thông qua kết quả (Paging through results)
Một phần mở rộng cho mệnh đề ORDER BY được gọi là OFFSET-FETCH cho phép bạn chỉ trả về một phạm vi các hàng được chọn bởi truy vấn của bạn. Phần mở rộng này cung cấp một cách thuận tiện để phân trang thông qua kết quả.
Cú pháp OFFSET-FETCH
Cú pháp của mệnh đề OFFSET-FETCH, về mặt kỹ thuật là một phần của mệnh đề ORDER BY, như sau:
OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS } [FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression } { ROW | ROWS } ONLY]
Cách sử dụng OFFSET-FETCH
Để sử dụng OFFSET-FETCH, bạn sẽ cung cấp giá trị OFFSET bắt đầu, có thể bằng 0 và số hàng tùy chọn để trả về, như trong ví dụ sau:
Ví dụ này sẽ trả về 10 hàng đầu tiên và sau đó trả về 10 hàng tiếp theo của dữ liệu sản phẩm dựa trên ListPrice:
SELECT ProductID, ProductName, ListPrice
FROM Production.Product
ORDER BY ListPrice DESC OFFSET 0 ROWS--Skip zero rows
FETCH NEXT 10 ROWS ONLY; -- Get the next 10
Để truy xuất trang tiếp theo của dữ liệu sản phẩm, hãy sử dụng mệnh đề OFFSET để chỉ định số hàng cần bỏ qua:
SELECT ProductID, ProductName, ListPrice
FROM Production.Product
ORDER BY ListPrice DESC OFFSET 10 ROWS--Skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- Get the next 10
Trong định nghĩa cú pháp, bạn có thể thấy mệnh đề OFFSET là bắt buộc, nhưng mệnh đề FETCH thì không. Nếu mệnh đề FETCH bị bỏ qua, tất cả các hàng sau OFFSET sẽ được trả về. Bạn cũng sẽ thấy rằng các từ khóa ROW và ROWS có thể hoán đổi cho nhau, cũng như FIRST và NEXT, điều này cho phép cú pháp tự nhiên hơn.
Để đảm bảo tính chính xác của kết quả, đặc biệt khi bạn di chuyển từ trang này sang trang dữ liệu khác, điều quan trọng là phải xây dựng mệnh đề ORDER BY sẽ cung cấp thứ tự duy nhất và mang lại kết quả xác định. Do cách thức hoạt động của trình tối ưu hóa truy vấn của SQL Server, về mặt kỹ thuật, một hàng có thể xuất hiện trên nhiều trang, trừ khi phạm vi của hàng là xác định.
Vậy là chúng ta vừa đi qua cách để sắp xếp kết quả truy vấn dựa vào sự trợ giúp vô cùng đắc lực từ công cụ Sort. Mình hy vọng rằng các bạn đọc có thể thực hành ngay bây giờ để có thể ghi nhớ và hiểu rõ hơn. Đừng quên, các bạn có thể tham khảo thêm về các khóa học SQL của Datapot tại đây nhé.
Tìm hiểu thêm về SQL cùng mình tại đây.