FresherLập trìnhSQL
Viết query đếm số đơn hàng của từng khách hàng
Thử trả lời trước
Đáp án mẫu
Join bảng customers với orders rồi group theo khách hàng. Dùng LEFT JOIN để khách chưa có đơn vẫn xuất hiện, và đếm một cột của bảng orders chứ không đếm *.
SELECT c.id,
c.name,
COUNT(o.id) AS order_count
FROM customers c
LEFT JOIN orders o ON o.customer_id = c.id
GROUP BY c.id, c.name
ORDER BY order_count DESC;
Với LEFT JOIN, khách không có đơn vẫn tạo ra một dòng mà o.id là NULL. COUNT(o.id) bỏ qua NULL nên trả về 0, còn COUNT(*) sẽ đếm dòng đó và trả về 1 một cách sai lệch.
Mọi cột được select mà không phải aggregate đều phải có trong GROUP BY. Một số engine chỉ cần c.id khi nó là primary key, nhưng liệt kê cả hai thì chạy được ở mọi nơi.
Nếu chỉ cần khách đã từng đặt hàng, INNER JOIN là đủ. Nếu muốn khách có ít nhất 5 đơn, lọc nhóm bằng HAVING COUNT(o.id) >= 5.
Hãy nhớ: đếm một cột thuộc phía tùy chọn của join.
Ý chính
- LEFT JOIN giữ lại khách chưa có đơn
- COUNT(o.id) bỏ qua NULL nên trả 0 cho họ
- Cột không phải aggregate phải nằm trong GROUP BY
- HAVING lọc nhóm sau khi đếm
Câu hỏi nối tiếp thường gặp
- Làm sao liệt kê chỉ những khách không có đơn?
Lỗi thường gặp
- Dùng COUNT(*) sau LEFT JOIN và nhận 1 thay vì 0
- Đặt điều kiện aggregate trong WHERE thay vì HAVING