首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server DATEADD 與 DATEDIFF 日期運算完全指南:常用週期邊界計算範例

     編輯:關於SqlServer

核心函數回顧

函數用途語法
DATEDIFF計算兩日期間的間隔數(年/月/週/日/時/分/秒/毫秒)DATEDIFF(interval, startdate, enddate)
DATEADD在指定日期加減間隔,回傳新日期DATEADD(interval, number, date)

關鍵技巧:以「基準日」0(即 1900-01-01 00:00:00.000)為錨點,計算目標日期與基準日的間隔數,再加回基準日,即可截取所需週期邊界。

常用週期邊界計算範本

需求T-SQL說明
本月第一天 00:00DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)月間隔數加回基準日
本週一 00:00DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()), 0)預設週一為週首(受 SET DATEFIRST 影響)
今年第一天 00:00DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)
本季第一天 00:00DATEADD(QUARTER, DATEDIFF(QUARTER, 0, GETDATE()), 0)
今天 00:00 (午夜)DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)截掉時間部分
上個月最後一天 23:59:59.997DATEADD(MS, -3, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0))本月第一天減 3 毫秒
去年最後一天 23:59:59.997DATEADD(MS, -3, DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0))
本月最後一天 23:59:59.997DATEADD(MS, -3, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()) + 1, 0))下月第一天減 3 毫秒
今年最後一天 23:59:59.997DATEADD(MS, -3, DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()) + 1, 0))
本月第一個週一DATEADD(WEEK, DATEDIFF(WEEK, 0, DATEADD(DAY, 6 - DATEPART(DAY, GETDATE()), GETDATE())), 0)先算本月 6 號,再取該週週一

間隔代碼速查

間隔代碼 (縮寫)
年year, yy, yyyy
季quarter, qq, q
月month, mm, m
週week, wk, ww
日day, dd, d
時hour, hh
分minute, mi, n
秒second, ss, s
毫秒millisecond, ms

實務應用範例

1. 當月營收統計篩選

DECLARE @StartOfMonth DATETIME = DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0);
DECLARE @StartOfNextMonth DATETIME = DATEADD(MONTH, 1, @StartOfMonth);

SELECT SUM(Amount) AS MonthlyRevenue
FROM Sales
WHERE OrderDate >= @StartOfMonth
  AND OrderDate < @StartOfNextMonth;  -- 半開區間,避免最後一天時間部分遺漏

2. 近 30 天滾動視窗

WHERE EventDate >= DATEADD(DAY, -30, CAST(GETDATE() AS DATE))
  AND EventDate < CAST(GETDATE() AS DATE);

3. 依週分組統計(週一為週首)

SELECT 
    DATEADD(WEEK, DATEDIFF(WEEK, 0, OrderDate), 0) AS WeekStart,
    COUNT(*) AS OrderCount
FROM Orders
GROUP BY DATEADD(WEEK, DATEDIFF(WEEK, 0, OrderDate), 0)
ORDER BY WeekStart;

注意事項

  • SET DATEFIRST 影響 WEEK 間隔的週首定義(1=週一, 7=週日,預設 7)。跨環境部署建議明確設定或改用 DATEPART(WEEKDAY, ...) 邏輯。
  • DATETIME 精度 3.33 ms,故「一天結束」用 23:59:59.997;DATETIME2/DATE 建議改用半開區間 < NextPeriodStart。
  • 避免在 WHERE 子句對欄位使用函數(如 WHERE DATEADD(...)=...),導致索引失效;改用常數邊界比較。

現代替代方案(SQL Server 2022+ / Azure SQL)

-- DATETRUNC (2022+) 直接截斷到指定精度
SELECT DATETRUNC(MONTH, GETDATE()) AS MonthStart;
SELECT DATETRUNC(WEEK, GETDATE()) AS WeekStart;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved