Giải pháp: DATE_SUB() hoặc INTERVAL
Sử dụng so sánh ngày với NOW() hoặc CURDATE() trừ đi interval.
Ví dụ minh họa
Tạo bảng
mysql> CREATE TABLE DemoTable (
LoginDate DATE
);
mysql> INSERT INTO DemoTable VALUES('2018-03-21');
mysql> INSERT INTO DemoTable VALUES('2019-05-22');
mysql> INSERT INTO DemoTable VALUES('2019-05-27');
mysql> INSERT INTO DemoTable VALUES('2019-06-01');
Giả sử hôm nay: 2019-06-02
Truy vấn: 7 ngày gần nhất
mysql> SELECT * FROM DemoTable
-> WHERE DATE(LoginDate) > (NOW() - INTERVAL 7 DAY);
Kết quả
+------------+ | LoginDate | +------------+ | 2019-05-27 | | 2019-06-01 | +------------+
Các cách viết tương đương
| Cú pháp | Giải thích |
|---|---|
DATE(col) > NOW() - INTERVAL 7 DAY | Dùng NOW() (datetime), so sánh sau khi DATE() |
DATE(col) > CURDATE() - INTERVAL 7 DAY | Dùng CURDATE() (date only), chuẩn hơn |
DATE(col) >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) | Dùng hàm DATE_SUB() tường minh |
col >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) | Không DATE() nếu col đã là DATE |
col BETWEEN DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND CURDATE() | Dùng BETWEEN (inclusive) |
⚠️ Lưu ý hiệu năng QUAN TRỌNG
Không dùng hàm trên cột nếu muốn dùng index:
-- ❌ Chậm - không dùng index WHERE DATE(LoginDate) > DATE_SUB(NOW(), INTERVAL 7 DAY) -- ✅ Nhanh - dùng index trên LoginDate WHERE LoginDate > DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND LoginDate <= CURDATE()
Mở rộng: Các khoảng thời gian thường dùng
-- 30 ngày qua WHERE LoginDate >= DATE_SUB(CURDATE(), INTERVAL 30 DAY) -- Tháng này WHERE LoginDate >= DATE_FORMAT(CURDATE(), '%Y-%m-01') AND LoginDate < DATE_FORMAT(CURDATE() + INTERVAL 1 MONTH, '%Y-%m-01') -- Tuần này (Thứ 2 - CN) WHERE LoginDate >= DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY) AND LoginDate < DATE_SUB(CURDATE(), INTERVAL WEEKDAY(CURDATE()) DAY) + INTERVAL 7 DAY