Giải pháp: CASE WHEN trong SUM()
Dùng SUM(CASE WHEN condition THEN 1 ELSE 0 END) để đếm có điều kiện.
Ví dụ minh họa
Tạo bảng và dữ liệu
mysql> CREATE TABLE DemoTable (Number INT); mysql> INSERT INTO DemoTable VALUES(10), (0), (20), (50), (0), (0), (40);
Dữ liệu gốc
+--------+ | Number | +--------+ | 10 | | 0 | | 20 | | 50 | | 0 | | 0 | | 40 | +--------+
Truy vấn đếm điều kiện
mysql> SELECT
-> SUM(CASE WHEN Number > 0 THEN 1 ELSE 0 END) AS TotalGreaterThanZero,
-> SUM(CASE WHEN Number = 0 THEN 1 ELSE 0 END) AS TotalEqualToZero
-> FROM DemoTable
-> WHERE Number >= 0;
Kết quả
+------------------------+--------------------+ | TotalGreaterThanZero | TotalEqualToZero | +------------------------+--------------------+ | 4 | 3 | +------------------------+--------------------+
Giải thích
CASE WHEN Number > 0 THEN 1 ELSE 0 END: Trả về 1 nếu >0, ngược lại 0SUM(...): Cộng dồn → đếm số dòng thỏa mãnWHERE Number >= 0: Loại trừ số âm (nếu có)
Cách thay thế: COUNT(CASE...)
SELECT
COUNT(CASE WHEN Number > 0 THEN 1 END) AS gt_zero,
COUNT(CASE WHEN Number = 0 THEN 1 END) AS eq_zero
FROM DemoTable;
COUNT(expr) đếm expr NOT NULL. CASE không có ELSE trả về NULL khi false.
MySQL 8.0+: CTE cho đọc dễ
WITH stats AS (
SELECT
CASE
WHEN Number > 0 THEN 'positive'
WHEN Number = 0 THEN 'zero'
ELSE 'negative'
END AS category
FROM DemoTable
)
SELECT category, COUNT(*) FROM stats GROUP BY category;
Ứng dụng: Dashboard thống kê
SELECT
COUNT(*) AS total_orders,
SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) AS completed,
SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) AS pending,
SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) AS cancelled,
SUM(CASE WHEN amount > 1000 THEN 1 ELSE 0 END) AS high_value
FROM orders;
So sánh COUNT vs SUM cho điều kiện
| Phương pháp | Cú pháp | Lưu ý |
|---|---|---|
| SUM(CASE...) | SUM(CASE WHEN cond THEN 1 ELSE 0 END) | Luôn trả về số (0 nếu không có) |
| COUNT(CASE...) | COUNT(CASE WHEN cond THEN 1 END) | NULL khi false, COUNT bỏ qua NULL |
| SUM(cond) | SUM(Number > 0) | MySQL: TRUE=1, FALSE=0. Ngắn gọn! |
Mẹo MySQL: Boolean SUM
SELECT
SUM(Number > 0) AS gt_zero,
SUM(Number = 0) AS eq_zero,
SUM(Number < 0) AS lt_zero
FROM DemoTable;
Ngắn gọn, hiệu năng tốt, MySQL-specific.