Vấn đề
Hàm SUM() trả về NULL (không phải 0) khi không có hàng thỏa mãn điều kiện WHERE.
Giải pháp: COALESCE()
Bọc SUM() trong COALESCE() để chuyển NULL thành 0:
SELECT COALESCE(SUM(ten_cot), 0) AS ten_alias FROM ten_bang WHERE dieu_kien;
Ví dụ chi tiết
1. Tạo bảng
mysql> CREATE TABLE SumDemo ( -> Words VARCHAR(100), -> Counter INT -> ); Query OK, 0 rows affected (0.93 sec)
2. Chèn dữ liệu
mysql> INSERT INTO SumDemo VALUES('Are You There',10);
Query OK, 1 row affected (0.16 sec)
mysql> INSERT INTO SumDemo VALUES('Are You Not There',15);
Query OK, 1 row affected (0.13 sec)
mysql> INSERT INTO SumDemo VALUES('Hello This is MySQL',12);
Query OK, 1 row affected (0.09 sec)
mysql> INSERT INTO SumDemo VALUES('Hello This is not MySQL',14);
Query OK, 1 row affected (0.24 sec)
3. Dữ liệu
mysql> SELECT * FROM SumDemo;
+-------------------------+---------+ | Words | Counter | +-------------------------+---------+ | Are You There | 10 | | Are You Not There | 15 | | Hello This is MySQL | 12 | | Hello This is not MySQL | 14 | +-------------------------+---------+ 4 rows in set (0.00 sec)
4. Có bản ghi khớp (chứa 'hello')
mysql> SELECT COALESCE(SUM(Counter), 0) AS SumOfAll -> FROM SumDemo WHERE Words LIKE '%hello%';
+----------+ | SumOfAll | +----------+ | 26 | +----------+ 1 row in set (0.00 sec)
5. Không có bản ghi khớp (chứa 'End of MySQL')
mysql> SELECT COALESCE(SUM(Counter), 0) AS SumOfAll -> FROM SumDemo WHERE Words LIKE '%End of MySQL%';
+----------+ | SumOfAll | +----------+ | 0 | +----------+ 1 row in set (0.00 sec)
So sánh COALESCE vs IFNULL vs CASE
| Cách viết | Cú pháp | Chuẩn SQL | Đánh giá |
|---|---|---|---|
| COALESCE | COALESCE(SUM(cot), 0) | ✅ ANSI | Khuyên dùng - nhiều tham số, chuẩn |
| IFNULL | IFNULL(SUM(cot), 0) | ❌ MySQL only | OK cho 2 giá trị |
| CASE | CASE WHEN SUM(cot) IS NULL THEN 0 ELSE SUM(cot) END | ✅ ANSI | Dài, chậm hơn |
Ứng dụng thực tế
Báo cáo doanh thu theo ngày (có ngày không bán hàng)
SELECT
sale_date,
COALESCE(SUM(amount), 0) AS daily_revenue
FROM sales
WHERE sale_date BETWEEN '2024-01-01' AND '2024-01-31'
GROUP BY sale_date
ORDER BY sale_date;
Tổng hợp nhiều cột cùng lúc
SELECT
COALESCE(SUM(sales), 0) AS total_sales,
COALESCE(SUM(returns), 0) AS total_returns,
COALESCE(SUM(profit), 0) AS total_profit
FROM daily_stats
WHERE month = 1;
Lưu ý
COALESCEđánh giá từ trái sang phải, trả về giá trị đầu tiên không NULL- Kiểu dữ liệu kết quả theo kiểu của tham số đầu tiên không NULL
- Áp dụng tương tự cho
AVG(),MIN(),MAX()(cũng trả về NULL khi rỗng)