Giới thiệu
Sử dụng MONTH(), YEAR() và CURDATE() để lọc bản ghi trong tháng/năm hiện tại, sau đó SUM() tính tổng.
1. Tạo bảng và dữ liệu
mysql> create table DemoTable1562 (
-> VoucherValue int,
-> RechargeDate date
-> );
Query OK, 0 rows affected (1.40 sec)
mysql> insert into DemoTable1562 values(149,'2019-10-21');
Query OK, 1 row affected (0.11 sec)
mysql> insert into DemoTable1562 values(199,'2019-10-13');
Query OK, 1 row affected (0.18 sec)
mysql> insert into DemoTable1562 values(399,'2018-10-13');
Query OK, 1 row affected (0.25 sec)
mysql> insert into DemoTable1562 values(450,'2019-10-13');
Query OK, 1 row affected (0.20 sec)
2. Dữ liệu và ngày hiện tại
mysql> select * from DemoTable1562;
+--------------+--------------+ | VoucherValue | RechargeDate | +--------------+--------------+ | 149 | 2019-10-21 | | 199 | 2019-10-13 | | 399 | 2018-10-13 | | 450 | 2019-10-13 | +--------------+--------------+ 4 rows in set (0.00 sec) mysql> select curdate(); +------------+ | curdate() | +------------+ | 2019-10-13 | +------------+ 1 row in set (0.00 sec)
3. Truy vấn tổng voucher tháng/năm hiện tại
mysql> select sum(VoucherValue) from DemoTable1562
-> where month(RechargeDate) = month(curdate())
-> and year(RechargeDate) = year(curdate());
4. Kết quả
+-------------------+ | sum(VoucherValue) | +-------------------+ | 798 | +-------------------+ 1 row in set (0.00 sec)
Giải thích: Chỉ tính các hàng năm 2019 tháng 10: 149 + 199 + 450 = 798. Hàng 399 (năm 2018) bị loại.
Cách viết tối ưu hơn (dùng index trên RechargeDate):
WHERE RechargeDate >= DATE_FORMAT(CURDATE(), '%Y-%m-01') AND RechargeDate < DATE_FORMAT(CURDATE(), '%Y-%m-01') + INTERVAL 1 MONTH
Cách này cho phép MySQL dùng index range scan trên cột RechargeDate, thay vì full scan do hàm MONTH/YEAR.
Mở rộng: Tổng từ đầu năm đến nay (YTD)
WHERE RechargeDate >= DATE_FORMAT(CURDATE(), '%Y-01-01') AND RechargeDate <= CURDATE()