Kỹ thuật: Conditional Aggregation với SUM()
Dùng SUM(condition) vì MySQL ép TRUE=1, FALSE=0.
Ví dụ
Tạo bảng:
CREATE TABLE DemoTable636 (
StudentId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
StudentFirstName VARCHAR(100)
);
INSERT INTO DemoTable636(StudentFirstName) VALUES
('John'), ('Robert'), ('Robert'), ('Sam'), ('Mike'), ('John'), ('Robert');
Đếm từng tên cụ thể:
SELECT
SUM(StudentFirstName = 'John') AS JOHN_COUNT,
SUM(StudentFirstName = 'Robert') AS ROBERT_COUNT,
SUM(StudentFirstName = 'Sam') AS SAM_COUNT,
SUM(StudentFirstName = 'Mike') AS MIKE_COUNT
FROM DemoTable636;
Kết quả:
+------------+--------------+-----------+------------+
| JOHN_COUNT | ROBERT_COUNT | SAM_COUNT | MIKE_COUNT |
+------------+--------------+-----------+------------+
| 2 | 3 | 1 | 1 |
+------------+--------------+-----------+------------+
So sánh các phương pháp
| Phương pháp | Cú pháp | Ưu điểm | Nhược điểm |
|---|---|---|---|
| SUM(boolean) | SUM(col='value') | Ngắn gọn, 1 pass, pivot table | Phải biết trước giá trị |
| COUNT(CASE) | COUNT(CASE WHEN col='value' THEN 1 END) | Chuẩn SQL, rõ ràng | Verbose |
| GROUP BY | GROUP BY col + COUNT(*) | Tự động tất cả giá trị | Kết quả dọc (rows), không phải ngang (columns) |
| PIVOT (MySQL 8.0) | Không có PIVOT syntax | - | Dùng conditional aggregation |
Mở rộng: Dynamic values (không biết trước)
-- Chỉ GROUP BY
SELECT StudentFirstName, COUNT(*) AS cnt
FROM DemoTable636
GROUP BY StudentFirstName
ORDER BY cnt DESC;
Kết quả dạng dòng (dễ dùng cho chart, report):
+------------------+-----+
| StudentFirstName | cnt |
+------------------+-----+
| Robert | 3 |
| John | 2 |
| Mike | 1 |
| Sam | 1 |
+------------------+-----+
Lưu ý
SUM(col='value')chỉ hoạt động đúng vì MySQL boolean → integer conversion.- ANSI SQL: Dùng
COUNT(CASE WHEN col='value' THEN 1 END). - Index trên cột đếm tăng tốc đáng kể.