Bài tập: top 5 sản phẩm
Bạn sẽ học được
- Ghép
ORDER BYvàLIMITthành một câu top-N hoàn chỉnh. - Chọn đúng cột và đúng thứ tự cột theo đề bài.
- Hiểu cách bài chấm so sánh giá trị
numericvà thứ tự dòng. - Sửa các lỗi thường gặp mà không cần thử ngẫu nhiên.
- Tự kiểm tra kết quả trước khi nộp.
Khái niệm cốt lõi
Đề bài 5 sản phẩm đắt nhất:
Lấy
namevàpricecủa 5 sản phẩm đắt nhất, sắp xếp giảm dần theo giá.
Checklist năm câu hỏi:
| Câu hỏi | Trả lời | Thành phần SQL |
|---|---|---|
| Bảng nào? | products | FROM products |
| Cột nào? | name, price, đúng thứ tự này | SELECT name, price |
| Lọc gì? | Không | không có WHERE |
| Thứ tự? | Giá giảm dần | ORDER BY price DESC |
| Giới hạn? | 5 dòng | LIMIT 5 |
Đáp án:
SELECT name, price
FROM products
ORDER BY price DESC
LIMIT 5;Kết quả:
| name | price |
|---|---|
| Nồi chiên không dầu | 1690000.00 |
| Bàn phím cơ | 1250000.00 |
| Tai nghe Bluetooth | 890000.00 |
| Chuột không dây | 450000.00 |
| Giá kê laptop | 390000.00 |
Giá hiển thị với hai chữ số thập phân vì cột price có kiểu numeric(12,2). Trong trình soạn SQL của khóa học, kết quả có thể hiển thị 1690000 hoặc 1690000.00 tùy công cụ; bài chấm so sánh theo kiểu dữ liệu, không theo chuỗi hiển thị. Đừng thêm ROUND hay CAST chỉ để đổi hình thức — đề không yêu cầu, và thay đổi kiểu có thể làm bài chấm báo sai cột.
Điểm cần chú ý: thứ tự thực thi. PostgreSQL sắp xếp toàn bộ 9 sản phẩm theo giá giảm dần, sau đó mới cắt 5 dòng đầu. Nếu bạn nghĩ LIMIT chạy trước, bạn sẽ tưởng nó lấy 5 sản phẩm bất kỳ rồi sắp — sai cả về kết quả lẫn cách viết. Đây là lý do LIMIT luôn đứng sau ORDER BY trong câu lệnh.
Bài chấm so sánh ba thứ:
- Số cột và tên cột.
SELECT *trả 5 cột, đề yêu cầu 2 — sai. - Giá trị từng dòng. Sai một giá là sai cả bài.
- Thứ tự dòng khi đề yêu cầu sắp xếp. Đề nói "giảm dần theo giá", nên thứ tự là một phần của đáp án.
Bộ dữ liệu ẩn của bài này có cùng 9 sản phẩm, chỉ thêm khách và đơn hàng. Vì vậy kết quả trên bộ ẩn giống hệt bộ hiển thị. Nhưng đừng vì thế mà hardcode: thói quen viết quy tắc vẫn là thứ được kiểm tra xuyên suốt khóa học.
Nếu hai sản phẩm cùng giá ở vị trí thứ năm, LIMIT 5 sẽ chọn một trong hai tùy kế hoạch thực thi. Đề hiện tại không có giá trùng nên không xảy ra. Khi làm việc thật, hãy thêm , id vào ORDER BY để kết quả xác định — đó là câu trả lời cho câu hỏi "nếu bằng giá thì sao?".
Ví dụ chạy được
Trước khi viết đáp án, kiểm tra dữ liệu:
SELECT name, price
FROM products
ORDER BY price DESC;Chín dòng, từ Nồi chiên 1.690.000 xuống Sách SQL 180.000. Năm dòng đầu chính là đáp án. Việc xem toàn bộ danh sách giúp bạn chắc rằng không có sản phẩm nào bị bỏ sót do điều kiện lọc — ở đây không có WHERE, nên mọi sản phẩm đều tham gia.
Sau đó áp LIMIT:
SELECT name, price
FROM products
ORDER BY price DESC
LIMIT 5;Năm dòng như bảng trên. Đối chiếu thủ công: sản phẩm đắt nhất là Nồi chiên 1.690.000; thứ hai Bàn phím 1.250.000; thứ ba Tai nghe 890.000; thứ tư Chuột 450.000; thứ năm Giá kê 390.000. Sản phẩm thứ sáu là Bình giữ nhiệt 320.000 — chỉ kém 70.000, nên rất dễ nhầm nếu sắp sai chiều.
Ba lần thử sai thường gặp:
Lần 1 — quên DESC:
SELECT name, price FROM products ORDER BY price LIMIT 5;Trả năm sản phẩm rẻ nhất: Sách, Áo, Đèn, Bình, Giá kê. Bài chấm báo sai toàn bộ giá trị. Cách sửa: thêm DESC.
Lần 2 — LIMIT sai số:
SELECT name, price FROM products ORDER BY price DESC LIMIT 6;Trả sáu dòng, thừa Bình giữ nhiệt. Bài chấm báo thừa dòng. Cách sửa: đọc kỹ "5" trong đề.
Lần 3 — chọn thừa cột:
SELECT * FROM products ORDER BY price DESC LIMIT 5;Năm dòng đúng nhưng có năm cột. Bài chấm báo sai cột. Cách sửa: chỉ chọn name và price, đúng thứ tự.
Một lần thử khác đáng lưu ý:
SELECT name, price
FROM products
WHERE price >= 390000
ORDER BY price DESC;Câu này trả đúng năm dòng trên dữ liệu hiện tại — nhưng sai về bản chất. Nếu bộ dữ liệu ẩn có thêm sản phẩm giá 395.000, kết quả thành sáu dòng; nếu có sản phẩm giá 1.800.000, kết quả vẫn năm dòng nhưng khác thành phần. Đề nói "5 sản phẩm đắt nhất", không nói "sản phẩm từ 390.000 trở lên". LIMIT diễn đạt đúng quy tắc; ngưỡng giá chỉ là quan sát tình cờ.
Đây là bài học quan trọng nhất của chương: đừng suy ra quy tắc từ kết quả. Hãy viết quy tắc bằng SQL, rồi để SQL tạo ra kết quả.
Thực hành
- Nộp đáp án cho bài 5 sản phẩm đắt nhất (
top-5-expensive-products). - Viết biến thể lấy 3 sản phẩm rẻ nhất, kèm cột
category. Kết quả: Sách SQL (Sách), Áo thun (Thời trang), Đèn bàn (Gia dụng). - Lấy 3 sản phẩm đắt nhất trong nhóm Gia dụng. Kết quả: Nồi chiên, Giá kê, Bình giữ nhiệt. Viết
WHEREtrướcORDER BYvàLIMIT. - Thêm
idvàoORDER BYcủa đáp án và giải thích khi nào nó thay đổi kết quả. Trên dữ liệu hiện tại, kết quả không đổi.
Lỗi thường gặp
| Triệu chứng | Nguyên nhân | Cách sửa |
|---|---|---|
| Chấm báo sai toàn bộ giá trị | Thiếu DESC | Thêm DESC sau price |
| Chấm báo thừa/thiếu dòng | LIMIT sai số | Đọc đúng số trong đề |
| Chấm báo sai cột | Dùng SELECT * hoặc thêm cột | Chỉ chọn name, price |
| Chấm báo sai thứ tự | Không có ORDER BY hoặc sắp theo cột khác | ORDER BY price DESC |
| Đúng hiển thị, sai bộ ẩn | Dùng ngưỡng giá thay cho LIMIT | Diễn đạt quy tắc bằng ORDER BY + LIMIT |
Lỗi cuối cùng khó phát hiện vì màn hình không báo. Cách tự kiểm tra: hỏi "nếu dữ liệu có thêm một sản phẩm đắt hơn, truy vấn của mình có trả đúng năm sản phẩm đắt nhất không?". Nếu câu trả lời phụ thuộc vào một con số cứng, bạn đã viết sai quy tắc.
Tóm tắt
- Top-N =
ORDER BYđúng chiều +LIMIT n; thứ tự này không thể đảo. - Chọn đúng cột và đúng thứ tự cột theo đề.
numeric(12,2)có thể hiển thị hai chữ số thập phân; không cần ép kiểu.- Đừng thay
LIMITbằng ngưỡng giá — quy tắc phải đúng trên mọi dữ liệu. - Thêm cột duy nhất vào
ORDER BYkhi có khả năng giá trị trùng.
Bạn đã hoàn thành chương sắp xếp và giới hạn. Chương tiếp theo chuyển sang hàm tổng hợp và GROUP BY — nơi dữ liệu bắt đầu được tóm tắt thay vì liệt kê.
Dùng ← → để chuyển bài