Giải pháp: YEAR() và MONTH()
Sử dụng hàm YEAR() và MONTH() trích xuất năm/tháng từ cột DATE/DATETIME để lọc.
Ví dụ minh họa
Tạo bảng đơn hàng
mysql> CREATE TABLE DemoTable (
CustomerId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
CustomerName VARCHAR(20),
CustomerTotalBill INT,
PurchasingDate DATE
);
mysql> INSERT INTO DemoTable(CustomerName, CustomerTotalBill, PurchasingDate)
-> VALUES('John', 2000, '2019-01-21');
mysql> INSERT INTO DemoTable(CustomerName, CustomerTotalBill, PurchasingDate)
-> VALUES('Chris', 1000, '2019-01-31');
mysql> INSERT INTO DemoTable(CustomerName, CustomerTotalBill, PurchasingDate)
-> VALUES('Robert', 4500, '2018-01-01');
mysql> INSERT INTO DemoTable(CustomerName, CustomerTotalBill, PurchasingDate)
-> VALUES('Sam', 5500, '2017-02-12');
mysql> INSERT INTO DemoTable(CustomerName, CustomerTotalBill, PurchasingDate)
-> VALUES('Carol', 500, '2016-01-12');
Truy vấn tháng 1/2019
mysql> SELECT * FROM DemoTable
-> WHERE YEAR(PurchasingDate) = 2019
-> AND MONTH(PurchasingDate) = 1;
Kết quả
+------------+--------------+-------------------+----------------+ | CustomerId | CustomerName | CustomerTotalBill | PurchasingDate | +------------+--------------+-------------------+----------------+ | 1 | John | 2000 | 2019-01-21 | | 2 | Chris | 1000 | 2019-01-31 | +------------+--------------+-------------------+----------------+
Cách thay thế: DATE_FORMAT()
WHERE DATE_FORMAT(PurchasingDate, '%Y-%m') = '2019-01'
Cách tối ưu hiệu năng (SARGable)
Tránh hàm trên cột để tận dụng index:
WHERE PurchasingDate >= '2019-01-01' AND PurchasingDate < '2019-02-01'
Hoặc dùng LAST_DAY():
WHERE PurchasingDate BETWEEN '2019-01-01' AND LAST_DAY('2019-01-01')
So sánh hiệu năng
| Phương pháp | Sử dụng Index | Khuyến nghị |
|---|---|---|
| YEAR()/MONTH() | Không | Bảng nhỏ, ad-hoc query |
| DATE_FORMAT() | Không | Bảng nhỏ |
| Range (>= AND <) | Có | Khuyến nghị cho production |
Mở rộng: Thống kê theo tháng
SELECT
YEAR(PurchasingDate) AS year,
MONTH(PurchasingDate) AS month,
COUNT(*) AS order_count,
SUM(CustomerTotalBill) AS total_revenue
FROM DemoTable
GROUP BY YEAR(PurchasingDate), MONTH(PurchasingDate)
ORDER BY year DESC, month DESC;