So sánh DATETIME và tính khoảng cách ngày giữa 2 cột trong MySQL
Sử dụng hàm DATEDIFF() để tính hiệu số ngày giữa 2 cột DATETIME/DATE. Kết hợp với WHERE để lọc theo điều kiện tuổi/khoảng thời gian.
Ví dụ minh họa
Tạo bảng DemoTable (DOB và CurrentDate đều DATETIME):
mysql> CREATE TABLE DemoTable (DOB DATETIME, CurrentDate DATETIME); Query OK, 0 rows affected (0.59 sec)
Chèn dữ liệu (CurrentDate dùng CURDATE() - ngày hiện tại):
mysql> INSERT INTO DemoTable VALUES('1995-01-21', CURDATE());
Query OK, 1 row affected (0.18 sec)
mysql> INSERT INTO DemoTable VALUES('1998-11-01', CURDATE());
Query OK, 1 row affected (0.39 sec)
mysql> INSERT INTO DemoTable VALUES('2000-10-24', CURDATE());
Query OK, 1 row affected (0.22 sec)
Xem dữ liệu (giả sử CURDATE() = '2019-07-08'):
mysql> SELECT * FROM DemoTable;
+---------------------+---------------------+ | DOB | CurrentDate | +---------------------+---------------------+ | 1995-01-21 00:00:00 | 2019-07-08 00:00:00 | | 1998-11-01 00:00:00 | 2019-07-08 00:00:00 | | 2000-10-24 00:00:00 | 2019-07-08 00:00:00 | +---------------------+---------------------+ 3 rows in set (0.00 sec)
Lọc người lớn hơn 23 tuổi (tính theo năm xấp xỉ):
mysql> SELECT * FROM DemoTable WHERE (DATEDIFF(CurrentDate, DOB) / 365) > 23;
Kết quả (chỉ người sinh 1995 > 23 tuổi):
+---------------------+---------------------+ | DOB | CurrentDate | +---------------------+---------------------+ | 1995-01-21 00:00:00 | 2019-07-08 00:00:00 | +---------------------+---------------------+ 1 row in set (0.00 sec)
Giải thích
DATEDIFF(CurrentDate, DOB): Trả về số ngày chênh lệch (CurrentDate - DOB)/ 365: Chuyển sang năm (xấp xỉ, không tính năm nhuận)> 23: Lọc tuổi > 23
Cách tính tuổi CHÍNH XÁC (xử lý năm nhuận, sinh nhật chưa đến)
-- Cách 1: TIMESTAMPDIFF (khuyên dùng)
SELECT TIMESTAMPDIFF(YEAR, DOB, CurrentDate) AS Age FROM DemoTable;
-- Cách 2: Logic thủ công chính xác
SELECT
FLOOR(DATEDIFF(CurrentDate, DOB) / 365.25) AS Age_Approx,
CASE
WHEN DATE_FORMAT(CurrentDate, '%m-%d') >= DATE_FORMAT(DOB, '%m-%d')
THEN TIMESTAMPDIFF(YEAR, DOB, CurrentDate)
ELSE TIMESTAMPDIFF(YEAR, DOB, CurrentDate) - 1
END AS Age_Exact
FROM DemoTable;
So sánh DATEDIFF vs TIMESTAMPDIFF
| Hàm | Đơn vị | Đặc điểm |
|---|---|---|
DATEDIFF(d1, d2) | Ngày | d1 - d2, trả về INT, bỏ qua phần giờ |
TIMESTAMPDIFF(unit, d1, d2) | MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR | Tính chính xác theo lịch, trả về INT |
Ứng dụng: Tìm người sắp sinh nhật (trong 30 ngày tới)
SELECT * FROM DemoTable WHERE DATE_ADD(DOB, INTERVAL TIMESTAMPDIFF(YEAR, DOB, CURDATE())+1 YEAR) BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 30 DAY);