Vấn đề: Đếm số lần xuất hiện các giá trị cụ thể theo nhóm
Cần đếm: mỗi học sinh (FirstName) có bao nhiêu lần đạt 45 điểm, bao nhiêu lần đạt 98 điểm.
Giải pháp: SUM(CASE WHEN ... THEN 1 ELSE 0 END)
Kỹ thuật Conditional Aggregation – dùng hàm tổng hợp SUM trên biểu thức CASE trả về 1/0.
1. Tạo bảng và dữ liệu
CREATE TABLE DemoTable (
FirstName VARCHAR(20),
Marks INT
);
INSERT INTO DemoTable VALUES
('Chris', 45), ('David', 85), ('Chris', 55), ('Chris', 98), ('David', 98);
2. Truy vấn đếm có điều kiện
SELECT FirstName,
SUM(CASE WHEN Marks = 45 THEN 1 ELSE 0 END) AS Count_45,
SUM(CASE WHEN Marks = 98 THEN 1 ELSE 0 END) AS Count_98
FROM DemoTable
GROUP BY FirstName;
3. Kết quả
+-----------+----------+----------+
| FirstName | Count_45 | Count_98 |
+-----------+----------+----------+
| Chris | 1 | 1 |
| David | 0 | 1 |
+-----------+----------+----------+
Giải thích
CASE WHEN Marks = 45 THEN 1 ELSE 0 ENDtrả về 1 cho hàng thỏa mãn, 0 cho hàng còn lại.SUM()cộng dồn các 1/0 → chính là số lần xuất hiện.GROUP BY FirstNametách tính cho từng người.
Mở rộng: Pivot table (bảng xoay)
SELECT FirstName,
SUM(CASE WHEN Marks BETWEEN 90 AND 100 THEN 1 ELSE 0 END) AS `90-100`,
SUM(CASE WHEN Marks BETWEEN 70 AND 89 THEN 1 ELSE 0 END) AS `70-89`,
SUM(CASE WHEN Marks < 70 THEN 1 ELSE 0 END) AS `<70`
FROM DemoTable
GROUP BY FirstName;
Lưu ý hiệu suất
- Dùng chỉ mục trên cột
MarksvàFirstNamenếu bảng lớn. - MySQL 8.0+ hỗ trợ
COUNT(*) FILTER (WHERE ...)(chuẩn SQL:2003) nhưng MySQL chưa hỗ trợ – dùng CASE WHEN.