Để tìm các bản ghi có ngày tháng (bỏ qua năm) trùng với ngày hiện tại — ví dụ: tìm sinh nhật hôm nay, kỷ niệm ngày thành lập — MySQL cung cấp hàm MONTH() và DAY() để trích xuất thành phần tháng và ngày để so sánh.
Ví dụ minh họa
Tạo bảng ngày kỷ niệm:
mysql> CREATE TABLE DemoTable1429 (
AnniversaryDate DATE
);
Chèn dữ liệu (nhiều năm khác nhau):
mysql> INSERT INTO DemoTable1429 VALUES ('2019-09-29');
mysql> INSERT INTO DemoTable1429 VALUES ('2018-09-27');
mysql> INSERT INTO DemoTable1429 VALUES ('2016-09-28');
mysql> INSERT INTO DemoTable1429 VALUES ('2015-09-29');
Dữ liệu:
mysql> SELECT * FROM DemoTable1429;
+-----------------+ | AnniversaryDate | +-----------------+ | 2019-09-29 | | 2018-09-27 | | 2016-09-28 | | 2015-09-29 | +-----------------+
Ngày hiện tại:
mysql> SELECT CURDATE();
+------------+ | curdate() | +------------+ | 2019-09-29 | +------------+
Truy vấn lọc trùng ngày và tháng
mysql> SELECT * FROM DemoTable1429
WHERE MONTH(AnniversaryDate) = MONTH(CURDATE())
AND DAY(AnniversaryDate) = DAY(CURDATE());
Kết quả (2 bản ghi ngày 29/9):
+-----------------+ | AnniversaryDate | +-----------------+ | 2019-09-29 | | 2015-09-29 | +-----------------+
Các cách viết tương đương
| Cú pháp | Mô tả |
|---|---|
DATE_FORMAT(date, '%m-%d') = DATE_FORMAT(CURDATE(), '%m-%d') | So sánh chuỗi định dạng MM-DD |
MONTH(date) = MONTH(CURDATE()) AND DAY(date) = DAY(CURDATE()) | Tách thành phần so sánh (khuyên dùng) |
DAYOFYEAR(date) = DAYOFYEAR(CURDATE()) | So sánh thứ tự ngày trong năm (nhanh hơn) |
Ứng dụng thực tế
- Gửi email chúc mừng sinh nhật tự động hàng ngày.
- Nhắc nhở kỷ niệm ngày làm việc, ngày thành lập công ty.
- Lọc sự kiện lặp lại hàng năm.
Mẹo hiệu năng: Nên tạo index trên cột DATE. MySQL 8.0+ hỗ trợ functional index trên MONTH(date), DAY(date) hoặc DAYOFYEAR(date) để tối ưu truy vấn này.