Bài viết Learn & More

Bài 7: Sắp xếp và Giới hạn dữ liệu: ORDER BY, TOP, OFFSET FETCH

Bài viết này thuộc SQL ServerCơ bản.

Hãy tưởng tượng bạn đang duyệt một trang web bán hàng (như Shopee, Tiki). Hai tính năng bạn dùng nhiều nhất là gì? Đó là "Sắp xếp giá từ thấp đến cao" và chuyển trang "Xem trang 1, trang 2" (Phân trang - Pagination). Làm thế nào Database có thể trả về dữ liệu đúng theo thứ tự và chỉ trả về một lượng nhỏ dữ liệu cho mỗi trang? Bài viết này sẽ cung cấp cho bạn 3 "bảo bối" để giải bài toán đó.

1. Sắp xếp dữ liệu với ORDER BY
Mặc định, khi bạn chạy lệnh SELECT, SQL Server sẽ trả dữ liệu về theo một thứ tự "bất kỳ" (thường là theo lúc được Insert vào hoặc theo cấu trúc vật lý của ổ cứng). Để ép nó sắp xếp theo ý muốn, ta dùng ORDER BY.

Cú pháp:
- ASC (Ascending): Tăng dần (Mặc định nếu không ghi gì).
- DESC (Descending): Giảm dần.

Ví dụ 1: Lấy danh sách sản phẩm, sắp xếp theo Giá TĂNG dần.

SELECT ProductName, Price 
FROM Products
ORDER BY Price ASC;

Ví dụ 2: Lấy danh sách Đơn hàng, sắp xếp theo Ngày mua MỚI NHẤT lên đầu (tức là ngày giảm dần). Nếu cùng ngày, xếp theo Tổng tiền giảm dần.

SELECT OrderID, OrderDate, TotalAmount 
FROM Orders
ORDER BY OrderDate DESC, TotalAmount DESC;

2. Giới hạn số lượng kết quả trả về với TOP
Đôi khi bảng của bạn có hàng triệu dòng, bạn chỉ muốn xem thử 5 dòng đầu tiên, hoặc muốn tìm "Top 3 sản phẩm đắt nhất". Mệnh đề TOP sinh ra để làm việc này.

Lưu ý: Mệnh đề TOP thường luôn đi kèm với ORDER BY. Nếu không có ORDER BY, 3 kết quả lấy ra sẽ là 3 kết quả ngẫu nhiên.

Ví dụ: Tìm 3 sản phẩm có giá trị cao nhất (Đắt nhất).

SELECT TOP 3 ProductName, Price
FROM Products
ORDER BY Price DESC;

Giải thích: SQL Server sẽ lấy toàn bộ sản phẩm -> Sắp xếp giá giảm dần -> Cắt lấy đúng 3 dòng trên cùng.

3. Kỹ thuật Phân trang (Pagination) với OFFSET ... FETCH
Đây là kỹ thuật CỰC KỲ QUAN TRỌNG khi làm Web/App. Khách hàng đang ở Trang số 2, mỗi trang hiển thị 10 sản phẩm. Làm sao để SQL trả về đúng sản phẩm thứ 11 đến 20?

SQL Server từ bản 2012 cung cấp cụm từ khóa:
- OFFSET n ROWS: Bỏ qua n dòng đầu tiên.
- FETCH NEXT m ROWS ONLY: Lấy m dòng tiếp theo.

Ví dụ: Giả sử mỗi trang hiển thị 2 sản phẩm. Lấy các sản phẩm ở Trang số 2 (sắp xếp theo Giá tăng dần).
Trang 1: Bỏ qua 0, lấy 2.
Trang 2: Bỏ qua 2, lấy 2.

SELECT ProductName, Price
FROM Products
ORDER BY Price ASC
OFFSET 2 ROWS 
FETCH NEXT 2 ROWS ONLY;

Bắt buộc: OFFSET FETCH yêu cầu CHẮC CHẮN phải có mệnh đề ORDER BY đi kèm, nếu không sẽ báo lỗi cú pháp.

Thực hành
Dựa vào bảng Customers và Orders trong ShopDB:
1. Hãy tìm ra 2 khách hàng đăng ký tài khoản (CreatedAt) sớm nhất hệ thống.
2. Viết câu lệnh lấy ra đơn hàng có tổng tiền (TotalAmount) cao thứ 2 trong hệ thống (Sử dụng OFFSET FETCH).

Tổng kết (Key Takeaways)
- ORDER BY dùng để sắp xếp (ASC: Tăng, DESC: Giảm).
- TOP dùng để giới hạn số dòng trả về, rất hữu ích khi làm chức năng "Top bán chạy", "Top giá cao".
- OFFSET ... FETCH là chuẩn mực để làm chức năng Phân trang (Pagination) trên Website.
- Luôn nhớ: TOP và OFFSET FETCH nên/phải đi kèm với ORDER BY để kết quả có ý nghĩa.

Điều hướng (Next Steps)
Đến đây bạn đã nắm vững cách thao tác trên MỘT BẢNG. Nhưng giá trị thực sự của Database nằm ở sự liên kết giữa các bảng. Mời bạn tiến vào kiến thức khó nhất nhưng thú vị nhất của SQL: [Bài 8: Tư duy về JOIN - Nghệ thuật Nối bảng (Phần 1: INNER JOIN)].

Nội dung liên quan

Thêm bài viết trong danh mục này