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

SQL Server 常用日期計算函數速查:月首、周一、年首、季首、月末、年末

     編輯:關於SqlServer

核心原理

利用 `DATEDIFF` 計算基準日期 (1900-01-01) 到目前的時間間隔數,再用 `DATEADD` 加回去,即可對齊到該時間單位的起始點。再配合 `DATEADD(ms, -3, ...)` 取得上一個時間單位的結束瞬間 (精確到 3.33ms)。

常用日期邊界計算

需求T-SQL 範例說明
本月第一天 00:00:00.000`DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0)`對齊到月首
本周一 00:00:00.000`DATEADD(wk, DATEDIFF(wk, 0, GETDATE()), 0)`以 1900-01-01 (週一) 為基準
今年第一天 00:00:00.000`DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0)`對齊到年首
本季第一天 00:00:00.000`DATEADD(qq, DATEDIFF(qq, 0, GETDATE()), 0)`對齊到季首
今天午夜 00:00:00.000`DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0)`移除時間部分
上月最後瞬間 23:59:59.997`DATEADD(ms, -3, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0))`本月首減 3ms
去年最後瞬間`DATEADD(ms, -3, DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0))`今年首減 3ms
本月最後瞬間`DATEADD(ms, -3, DATEADD(mm, DATEDIFF(mm, 0, GETDATE())+1, 0))`下月首減 3ms
今年最後瞬間`DATEADD(ms, -3, DATEADD(yy, DATEDIFF(yy, 0, GETDATE())+1, 0))`明年首減 3ms
本月第一個週一`DATEADD(wk, DATEDIFF(wk, 0, DATEADD(dd, 6-DATEPART(day, GETDATE()), GETDATE())), 0)`先算本月 1 號對應的週一

進階應用模式

日期區間查詢 (含邊界)

-- 本月完整資料
WHERE dt >= DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0)
  AND dt <  DATEADD(mm, DATEDIFF(mm, 0, GETDATE())+1, 0);

使用 `< 下月首` 而非 `<= 本月末`,避免時間精度問題 (datetime 精度 3.33ms)。

動態報表參數化

DECLARE @StartOfMonth DATETIME = DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0);
DECLARE @EndOfMonth   DATETIME = DATEADD(ms, -3, DATEADD(mm, DATEDIFF(mm, 0, GETDATE())+1, 0));

相對週期計算

  • 上月首:`DATEADD(mm, -1, DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0))`
  • 下季首:`DATEADD(qq, 1, DATEADD(qq, DATEDIFF(qq, 0, GETDATE()), 0))`

注意事項

  • 基準日期 `0` = `1900-01-01` (週一),`wk` 間隔以此為基準對齊週一。
  • `DATEADD(ms, -3, ...)` 取得上一個 datetime 刻度點,適用 `DATETIME` 型別;`DATETIME2` 精度更高需調整毫秒數。
  • 所有函數為非確定性,不可用於計算欄位或索引檢視定義。

總結

掌握 `DATEDIFF`/`DATEADD` 組合模式,能靈活構建任意時間邊界,撰寫高效、無時區困擾的日期區間查詢。建議封裝為純量函數 (Scalar UDF) 或 CTE 共用,提升程式碼可讀性與維護性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved