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

更多 MySQL 相關的日期時間函數在這邊
更多 SQL Server 相關的日期時間函數在這邊