Giải pháp: 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 giao hàng
mysql> CREATE TABLE DemoTable (
Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
ShippingDate DATETIME
);
mysql> INSERT INTO DemoTable(ShippingDate) VALUES('2019-01-31');
mysql> INSERT INTO DemoTable(ShippingDate) VALUES('2018-12-01');
mysql> INSERT INTO DemoTable(ShippingDate) VALUES('2019-06-02');
mysql> INSERT INTO DemoTable(ShippingDate) VALUES('2019-11-18');
Dữ liệu gốc
+----+-----------------------+ | Id | ShippingDate | +----+-----------------------+ | 1 | 2019-01-31 00:00:00 | | 2 | 2018-12-01 00:00:00 | | 3 | 2019-06-02 00:00:00 | | 4 | 2019-11-18 00:00:00 | +----+-----------------------+
Truy vấn: Tháng 6 năm 2019
mysql> SELECT * FROM DemoTable
-> WHERE YEAR(ShippingDate) = 2019
-> AND MONTH(ShippingDate) = 6;
Kết quả
+----+-----------------------+ | Id | ShippingDate | +----+-----------------------+ | 3 | 2019-06-02 00:00:00 | +----+-----------------------+
Các cách viết khác
| Phương pháp | Cú pháp | Sử dụng Index |
|---|---|---|
| YEAR()/MONTH() | YEAR(col)=2019 AND MONTH(col)=6 | Không |
| DATE_FORMAT() | DATE_FORMAT(col, '%Y-%m') = '2019-06' | Không |
| Range (Khuyến nghị) | col >= '2019-06-01' AND col < '2019-07-01' | Có |
| LAST_DAY() | col BETWEEN '2019-06-01' AND LAST_DAY('2019-06-01') | Có |
Tối ưu hóa cho bảng lớn
-- Tạo index CREATE INDEX idx_shipping_date ON DemoTable(ShippingDate); -- Query tối ưu SELECT * FROM DemoTable WHERE ShippingDate >= '2019-06-01' AND ShippingDate < '2019-07-01';
Mở rộng: Thống kê theo tháng/năm
SELECT
YEAR(ShippingDate) AS year,
MONTH(ShippingDate) AS month,
COUNT(*) AS shipments,
SUM(amount) AS total_amount
FROM DemoTable
GROUP BY YEAR(ShippingDate), MONTH(ShippingDate)
ORDER BY year DESC, month DESC;
Lưu ý
- YEAR()/MONTH() trả về số nguyên (2019, 6)
- So sánh số:
YEAR(col) = 2019(không cần quote) - DATE_FORMAT trả về string:
'2019-06'(cần quote) - Range query nhanh hơn rất nhiều trên bảng có index