Truy vấn chạy, không báo lỗi, và trả về nhiều hơn đúng 40%. Nguyên nhân nằm ở thứ tự ưu tiên mà không ai dạy bạn.
Bài toán
Bạn cần lấy khách VIP ở Việt Nam hoặc Mỹ. Câu viết ra rất tự nhiên:
SELECT * FROM khach_hang
WHERE quoc_gia = 'VN' OR quoc_gia = 'US' AND vip = 1;
Kết quả trả về cả khách Việt Nam không phải VIP. Không có lỗi cú pháp nào.
Lỗi thường gặp
SQL có thứ tự ưu tiên giống toán học: NOT > AND > OR. Máy đọc câu trên thành:
WHERE quoc_gia = 'VN'
OR (quoc_gia = 'US' AND vip = 1);
Tức là: “mọi khách Việt Nam, cộng thêm khách Mỹ là VIP”. Hoàn toàn khác ý bạn.
WHERE có cả AND lẫn OR, luôn đặt ngoặc quanh phần OR. Không có ngoại lệ.
Cách đúng
SELECT * FROM khach_hang
WHERE (quoc_gia = 'VN' OR quoc_gia = 'US')
AND vip = 1;
Với danh sách dài, IN gọn hơn và ít sai hơn:
WHERE quoc_gia IN ('VN','US','SG','TH')
AND vip = 1;
Bẫy đi kèm: NOT và NULL
-- Bỏ sót khách có quoc_gia = NULL
WHERE quoc_gia NOT IN ('VN','US')
-- An toàn
WHERE (quoc_gia NOT IN ('VN','US') OR quoc_gia IS NULL)
NULL không bằng và cũng không khác bất cứ giá trị nào, nên nó lặng lẽ rơi khỏi kết quả.
BETWEEN bao gồm cả hai đầu
WHERE tuoi BETWEEN 18 AND 25 -- gồm cả 18 và 25
Với kiểu ngày giờ, đừng dùng BETWEEN. BETWEEN '2026-01-01' AND '2026-01-31' sẽ bỏ sót mọi giao dịch sau 00:00 ngày 31. Dùng >= ngày_đầu AND < ngày_sau.
Luyện tập
- LeetCode 595 — Big Countries
- LeetCode 584 — Find Customer Referee (bẫy NULL kinh điển)
- LeetCode 1148 — Article Views I
- HackerRank — Weather Observation Station 6 đến 12
Tóm lại
ANDluôn được tính trướcOR.- Có cả hai trong một
WHEREthì bắt buộc đặt ngoặc. INthay cho chuỗiORdài.NOT INâm thầm bỏ sót dòng cóNULL.- Không dùng
BETWEENcho ngày giờ.
Bạn vừa học xong AND, OR và dấu ngoặc
Sẵn sàng luyện tập chưa?
Làm bài tập AND, OR và dấu ngoặc trên dữ liệu thật, chấm điểm ngay khi bạn bấm chạy.
Bắt đầu luyện tập →