Cú pháp cơ bản
Sử dụng UNIX_TIMESTAMP() chuyển đổi sang giây từ epoch (1970-01-01), sau đó trừ:
SELECT UNIX_TIMESTAMP(cot_1) - UNIX_TIMESTAMP(cot_2) AS chenh_lech_giay FROM ten_bang;
Ví dụ chi tiết
1. Tạo bảng
mysql> CREATE TABLE DifferenceInSeconds ( -> FirstTimestamp TIMESTAMP, -> SecondTimestamp TIMESTAMP -> ); Query OK, 0 rows affected (0.93 sec)
2. Chèn dữ liệu
mysql> INSERT INTO DifferenceInSeconds VALUES('2012-12-12 13:16:55','2012-12-12 13:13:55');
Query OK, 1 row affected (0.31 sec)
mysql> INSERT INTO DifferenceInSeconds VALUES('2014-10-11 12:15:50','2014-10-11 12:13:50');
Query OK, 1 row affected (0.19 sec)
mysql> INSERT INTO DifferenceInSeconds VALUES('2018-12-14 13:30:53','2018-12-14 13:27:53');
Query OK, 1 row affected (0.21 sec)
3. Dữ liệu gốc
mysql> SELECT * FROM DifferenceInSeconds;
+---------------------+---------------------+ | FirstTimestamp | SecondTimestamp | +---------------------+---------------------+ | 2012-12-12 13:16:55 | 2012-12-12 13:13:55 | | 2014-10-11 12:15:50 | 2014-10-11 12:13:50 | | 2018-12-14 13:30:53 | 2018-12-14 13:27:53 | +---------------------+---------------------+ 3 rows in set (0.00 sec)
4. Tính chênh lệch (First - Second)
mysql> SELECT UNIX_TIMESTAMP(FirstTimestamp) - UNIX_TIMESTAMP(SecondTimestamp) AS Seconds FROM DifferenceInSeconds;
+---------+ | Seconds | +---------+ | 180 | | 120 | | 180 | +---------+ 3 rows in set (0.00 sec)
Vấn đề: Không biết cột nào lớn hơn
Nếu FirstTimestamp < SecondTimestamp → kết quả âm.
Thêm bản ghi First < Second
mysql> INSERT INTO DifferenceInSeconds VALUES('2018-12-14 13:26:53','2018-12-14 13:31:53');
Query OK, 1 row affected (0.21 sec)
Kết quả không dùng ABS()
+---------+ | Seconds | +---------+ | 180 | | 120 | | 180 | | -300 | <-- Âm! +---------+
Giải pháp: Dùng ABS() lấy giá trị tuyệt đối
mysql> SELECT ABS(UNIX_TIMESTAMP(FirstTimestamp) - UNIX_TIMESTAMP(SecondTimestamp)) AS Seconds FROM DifferenceInSeconds;
+---------+ | Seconds | +---------+ | 180 | | 120 | | 180 | | 300 | <-- Dương +---------+ 4 rows in set (0.00 sec)
Phương pháp thay thế: TIMESTAMPDIFF
-- Chênh lệch giây (có dấu) SELECT TIMESTAMPDIFF(SECOND, SecondTimestamp, FirstTimestamp) AS diff_seconds FROM DifferenceInSeconds; -- Chênh lệch tuyệt đối SELECT ABS(TIMESTAMPDIFF(SECOND, SecondTimestamp, FirstTimestamp)) AS diff_seconds FROM DifferenceInSeconds;
So sánh UNIX_TIMESTAMP vs TIMESTAMPDIFF
| Đặc điểm | UNIX_TIMESTAMP() | TIMESTAMPDIFF() |
|---|---|---|
| Kết quả | Số giây (BIGINT) | Số nguyên (BIGINT) |
| Xử lý múi giờ | Tự động (TIMESTAMP) | Tự động |
| Hỗ trợ đơn vị | Chỉ giây | MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR |
| Thứ tự tham số | Tự trừ | TIMESTAMPDIFF(unit, datetime1, datetime2) = datetime2 - datetime1 |
| Khuyên dùng | Đơn giản, chỉ cần giây | Linh hoạt hơn, nhiều đơn vị |
Ứng dụng thực tế
Tính thời gian xử lý request
SELECT
request_id,
TIMESTAMPDIFF(MILLISECOND, start_time, end_time) AS duration_ms
FROM api_logs;
Tính tuổi chính xác (năm)
SELECT TIMESTAMPDIFF(YEAR, birthdate, CURDATE()) AS age FROM users;
Lưu ý
UNIX_TIMESTAMP()chỉ hoạt động cho TIMESTAMP (1970-2038), DATETIME ngoài phạm vi trả về NULLTIMESTAMPDIFFhoạt động với DATETIME đầy đủ (1000-9999)- Index trên cột timestamp không giúp tăng tốc phép trừ này