MySQL DATE_SUB() 函數 (在日期上減去時間間隔)
DATE_SUB() 是 MySQL 中用來在日期時間值上減去指定時間間隔的函數。它可以減去天、月、年、小時、分鐘、秒等各種時間單位。
如果需要增加時間間隔,可以使用 DATE_ADD() 函數,或者在 DATE_SUB() 中使用負數。
DATE_SUB() 語法 (Syntax)
DATE_SUB(date, INTERVAL expr unit)
- date:起始日期或日期時間。
- expr:要減去的時間間隔數量(正數表示減少,負數表示增加)。
- unit:時間間隔的單位(與 DATE_ADD() 相同)。
unit 可用的值
| unit | 說明 |
|---|---|
| MICROSECOND | 微秒 |
| SECOND | 秒 |
| MINUTE | 分鐘 |
| HOUR | 小時 |
| DAY | 天 |
| WEEK | 週 |
| MONTH | 月 |
| QUARTER | 季度 |
| YEAR | 年 |
| YEAR_MONTH | 年和月 |
| DAY_HOUR | 日和時 |
| DAY_MINUTE | 日、時和分 |
| DAY_SECOND | 日、時、分和秒 |
| HOUR_MINUTE | 時和分 |
| HOUR_SECOND | 時、分和秒 |
| MINUTE_SECOND | 分和秒 |
DATE_SUB() 函數用法範例 (Example)
減去天數
SELECT DATE_SUB('2024-05-01', INTERVAL 1 DAY);
-- 結果:2024-04-30
SELECT DATE_SUB('2024-01-01', INTERVAL 1 DAY);
-- 結果:2023-12-31(自動跨年)
SELECT DATE_SUB('2024-12-31 23:59:59', INTERVAL 1 DAY);
-- 結果:2024-12-30 23:59:59
減去週數
SELECT DATE_SUB('2024-11-22', INTERVAL 1 WEEK);
-- 結果:2024-11-15
SELECT DATE_SUB('2024-11-22', INTERVAL 2 WEEK);
-- 結果:2024-11-08
減去月份
SELECT DATE_SUB('2024-05-01', INTERVAL 1 MONTH);
-- 結果:2024-04-01
SELECT DATE_SUB('2024-03-31', INTERVAL 1 MONTH);
-- 結果:2024-02-29(2024 年是閏年,會自動調整為該月的最後一天)
SELECT DATE_SUB('2023-03-31', INTERVAL 1 MONTH);
-- 結果:2023-02-28(2023 年不是閏年)
減去年份
SELECT DATE_SUB('2024-05-01', INTERVAL 1 YEAR);
-- 結果:2023-05-01
SELECT DATE_SUB('2024-02-29', INTERVAL 1 YEAR);
-- 結果:2023-02-28(2023 年不是閏年,自動調整)
減去小時、分鐘、秒
SELECT DATE_SUB('2024-01-01 02:00:00', INTERVAL 3 HOUR);
-- 結果:2023-12-31 23:00:00
SELECT DATE_SUB('2024-05-01 10:30:00', INTERVAL 45 MINUTE);
-- 結果:2024-05-01 09:45:00
SELECT DATE_SUB('2024-01-01 00:00:00', INTERVAL 1 SECOND);
-- 結果:2023-12-31 23:59:59
使用負數增加時間
SELECT DATE_SUB('2024-05-01', INTERVAL -1 DAY);
-- 結果:2024-05-02
SELECT DATE_SUB('2024-05-01', INTERVAL -1 YEAR);
-- 結果:2025-05-01
實際應用範例
取得過去一段時間的記錄
-- 取得最近 7 天的訂單
SELECT * FROM orders
WHERE order_date >= DATE_SUB(NOW(), INTERVAL 7 DAY);
-- 取得最近 30 天的訂單
SELECT * FROM orders
WHERE order_date >= DATE_SUB(NOW(), INTERVAL 30 DAY);
-- 取得最近 1 小時的活動記錄
SELECT * FROM activity_logs
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 HOUR);
計算過去同期數據
-- 取得去年同月的銷售數據
SELECT
DATE_FORMAT(order_date, '%Y-%m') AS month,
SUM(amount) AS total_sales
FROM orders
WHERE order_date >= DATE_SUB(NOW(), INTERVAL 1 YEAR)
AND order_date < DATE_SUB(NOW(), INTERVAL 11 MONTH)
GROUP BY DATE_FORMAT(order_date, '%Y-%m');
清理過期資料
-- 刪除 90 天前的日誌記錄
DELETE FROM logs
WHERE created_at < DATE_SUB(NOW(), INTERVAL 90 DAY);
-- 刪除 1 年前的臨時數據
DELETE FROM temp_data
WHERE created_at < DATE_SUB(NOW(), INTERVAL 1 YEAR);
取得昨天、上週、上個月
SELECT
DATE_SUB(CURDATE(), INTERVAL 1 DAY) AS yesterday,
DATE_SUB(CURDATE(), INTERVAL 1 WEEK) AS last_week,
DATE_SUB(CURDATE(), INTERVAL 1 MONTH) AS last_month;
DATE_SUB() 與 - INTERVAL 的比較
MySQL 也支援使用 - 運算子直接減去 INTERVAL:
-- 以下兩種寫法結果相同
SELECT DATE_SUB('2024-05-01', INTERVAL 1 DAY);
SELECT '2024-05-01' - INTERVAL 1 DAY;
-- 結果都是:2024-04-30