FresherKỹ thuậtSQL
WHERE và HAVING khác nhau như thế nào?
Thử trả lời trước
Đáp án mẫu
WHERE lọc từng dòng trước khi group. HAVING lọc các nhóm sau khi aggregate, nên dùng được các hàm aggregate như COUNT hoặc SUM, điều mà WHERE không làm được.
SELECT customer_id, COUNT(*) AS orders, SUM(total) AS spent
FROM orders
WHERE status = 'paid' -- row filter, runs first
GROUP BY customer_id
HAVING SUM(total) > 1000; -- group filter, runs after
Thứ tự là: FROM, WHERE, GROUP BY, aggregate, HAVING, SELECT, ORDER BY. Đó là lý do WHERE SUM(total) > 1000 bị lỗi: khi WHERE chạy thì các tổng chưa tồn tại.
Hãy đặt mọi điều kiện không cần aggregate vào WHERE, đừng đặt vào HAVING. Nó loại dòng sớm nên có ít dòng phải group hơn, và cho phép database dùng index.
-- better: filter before grouping
WHERE customer_id = 7
-- worse: same filter after grouping
HAVING customer_id = 7
Hãy nhớ: WHERE lọc dòng, HAVING lọc nhóm.
Ý chính
- WHERE lọc dòng trước khi group
- HAVING lọc nhóm và dùng được aggregate
- Không dùng aggregate trong WHERE
- Điều kiện không aggregate nên đặt trong WHERE cho nhanh
Câu hỏi nối tiếp thường gặp
- Có dùng alias của cột trong HAVING được không?
Lỗi thường gặp
- Viết WHERE COUNT(*) > 1
- Lọc cột thường trong HAVING và phải group nhiều dòng hơn cần thiết