SQL Server DATEADD() 函數 (增加或減少指定的時間間隔)

DATEADD() 是 SQL Server 中用來在日期時間值上增加或減少指定時間間隔的函數。它可以處理年、月、日、小時、分鐘、秒等各種時間單位。

DATEADD() 語法 (Syntax)

DATEADD(datepart, number, date)
  • datepart:時間間隔的單位(見下方表格)。
  • number:要增加或減少的數量(正數表示增加,負數表示減少)。
  • date:起始日期或日期時間。
  • 返回值:與輸入 date 相同的資料型別。

datepart 可用的值

datepart (全名)縮寫說明
yearyy, yyyy
quarterqq, q季度
monthmm, m
dayofyeardy, y一年中的第幾天
daydd, d
weekwk, ww
weekdaydw, w星期幾
hourhh小時
minutemi, n分鐘
secondss, s
millisecondms毫秒
microsecondmcs微秒
nanosecondns奈秒

DATEADD() 函數用法範例 (Example)

增加天數

SELECT DATEADD(day, 1, '2024-11-22');
-- 結果:2024-11-23 00:00:00.000

SELECT DATEADD(day, 7, '2024-12-25');
-- 結果:2025-01-01 00:00:00.000(自動跨年)

減少天數

SELECT DATEADD(day, -1, '2024-11-22');
-- 結果:2024-11-21 00:00:00.000

SELECT DATEADD(day, -30, GETDATE());
-- 結果:30 天前的日期時間

增加/減少月份

SELECT DATEADD(month, 1, '2024-01-31');
-- 結果:2024-02-29 00:00:00.000(2024 是閏年)

SELECT DATEADD(month, 1, '2023-01-31');
-- 結果:2023-02-28 00:00:00.000(自動調整為該月最後一天)

SELECT DATEADD(month, -3, '2024-11-22');
-- 結果:2024-08-22 00:00:00.000

增加/減少年份

SELECT DATEADD(year, 1, '2024-02-29');
-- 結果:2025-02-28 00:00:00.000(2025 不是閏年,自動調整)

SELECT DATEADD(year, -5, GETDATE());
-- 結果:5 年前的日期時間

增加/減少小時

SELECT DATEADD(hour, 3, '2024-11-22 21:00:00');
-- 結果:2024-11-23 00:00:00.000(跨越到隔天)

SELECT DATEADD(hour, -6, GETDATE());
-- 結果:6 小時前

增加/減少分鐘和秒

SELECT DATEADD(minute, 45, '2024-11-22 10:30:00');
-- 結果:2024-11-22 11:15:00.000

SELECT DATEADD(second, 30, '2024-11-22 23:59:45');
-- 結果:2024-11-23 00:00:15.000

增加週數

SELECT DATEADD(week, 2, '2024-11-22');
-- 結果:2024-12-06 00:00:00.000

實際應用範例

計算訂閱到期日

SELECT
    user_id,
    subscription_start,
    DATEADD(month, 1, subscription_start) AS expiry_date_monthly,
    DATEADD(year, 1, subscription_start) AS expiry_date_yearly
FROM subscriptions;

計算預計送達日期

SELECT
    order_id,
    order_date,
    DATEADD(day, 3, order_date) AS estimated_delivery
FROM orders;

取得本月第一天

SELECT DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0) AS FirstDayOfMonth;
-- 結果:2024-11-01 00:00:00.000

取得本月最後一天

-- 方法 1:使用 EOMONTH(SQL Server 2012+)
SELECT EOMONTH(GETDATE()) AS LastDayOfMonth;

-- 方法 2:使用 DATEADD
SELECT DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, GETDATE()) + 1, 0)) AS LastDayOfMonth;

取得本週第一天(週一)

SELECT DATEADD(week, DATEDIFF(week, 0, GETDATE()), 0) AS FirstDayOfWeek;

取得今年第一天和最後一天

SELECT
    DATEADD(year, DATEDIFF(year, 0, GETDATE()), 0) AS FirstDayOfYear,
    DATEADD(day, -1, DATEADD(year, DATEDIFF(year, 0, GETDATE()) + 1, 0)) AS LastDayOfYear;

取得過去 N 天的記錄

-- 取得最近 7 天的訂單
SELECT * FROM orders
WHERE order_date >= DATEADD(day, -7, GETDATE());

-- 取得最近 30 天的訂單
SELECT * FROM orders
WHERE order_date >= DATEADD(day, -30, CAST(GETDATE() AS DATE));

計算未來某日期的時間點

-- 7 天後的凌晨 00:00:00
SELECT DATEADD(day, 7, CAST(GETDATE() AS DATE)) AS SevenDaysLater;

-- 下個月同一天的上午 10:00
SELECT DATEADD(hour, 10, DATEADD(month, 1, CAST(GETDATE() AS DATE))) AS NextMonthMorning;

結合 DATEADD 和 DATEDIFF 的技巧

SQL Server 中沒有直接取得「本月第一天」等的函數,但可以結合 DATEADD()DATEDIFF() 來實現:

-- 取得本季第一天
SELECT DATEADD(quarter, DATEDIFF(quarter, 0, GETDATE()), 0) AS FirstDayOfQuarter;

-- 取得去年同一天
SELECT DATEADD(year, -1, GETDATE()) AS SameDayLastYear;

-- 取得下個月的今天
SELECT DATEADD(month, 1, GETDATE()) AS SameDayNextMonth;

注意事項

  • 當增加月份導致日期超出該月的天數時,SQL Server 會自動調整為該月的最後一天。
  • DATEADD() 返回的資料型別與輸入的 date 參數相同。
  • 對於 datetime 型別,精度約為 3.33 毫秒;如需更高精度,請使用 datetime2

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