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

SQL Server 日期時間函數實戰指南:GETDATE、DATEADD、DATEDIFF、DATEPART 全解析

     編輯:關於SqlServer

日期時間函數是 T-SQL 查詢、ETL、排程的基石。本文透過實例詳解四大核心函數 GETDATE、DATEADD、DATEDIFF、DATEPART 的語法、行為差異與常見陷阱,並提供實戰查詢模式。

1. 取得系統當前時間

SELECT GETDATE()           -- 當前日期時間,精確到毫秒(約 3.33ms)
SELECT SYSDATETIME()       -- 高精度 datetime2,100ns 精度
SELECT SYSUTCDATETIME()    -- UTC 高精度時間

注意: GETDATE() 回傳 datetime,新專案建議改用 SYSDATETIME() 回傳 datetime2。

2. DATENAME:取得字串形式的日期部分

SELECT DATENAME(YEAR,   GETDATE())  -- '2024'
SELECT DATENAME(MONTH,  GETDATE())  -- '一月' (視語言而定)
SELECT DATENAME(WEEKDAY,GETDATE())  -- '星期一'
SELECT DATENAME(DAY,    GETDATE())  -- '15'

回傳 nvarchar,適合報表顯示、動態 SQL 拼接。

3. DATEADD:日期加減運算

SELECT DATEADD(MONTH, 2, '2008-08-08')   -- 2008-10-08 00:00:00.000
SELECT DATEADD(DAY,   2, '2008-08-08')   -- 2008-08-10 00:00:00.000
SELECT DATEADD(HOUR, -1, GETDATE())      -- 1 小時前
SELECT DATEADD(MINUTE, 30, GETDATE())    -- 30 分鐘後
SELECT DATEADD(SECOND, -10, GETDATE())   -- 10 秒前

間隔單位速查: year/yy/yyyy, quarter/qq/q, month/mm/m, dayofyear/dy/y, day/dd/d, week/ww/wk, weekday/dw, hour/hh, minute/mi/n, second/ss/s, millisecond/ms, microsecond/mcs, nanosecond/ns。

4. DATEDIFF:計算兩日期間的間隔數


SELECT DATEDIFF(HOUR,   '04:00', '05:50')          -- 1 (僅計算時鐘跨越次數)
SELECT DATEDIFF(MONTH,  '1987-05-02', '1995-11-15')-- 102
SELECT DATEDIFF(DAY,    '00:00',   '23:59')        -- 0 (同一天)
SELECT DATEDIFF(DAY,    '1999-07-19 00:00', '1999-07-23 23:59') -- 4
SELECT DATEDIFF(MONTH,  '1999-07-19', '1999-07-23')-- 0
SELECT DATEDIFF(MONTH,  '1999-07-19', '1999-08-23')-- 1

核心行為: 計算「邊界跨越次數」,非連續時間長度。例如 DATEDIFF(DAY, '23:59', '00:01') 回傳 1(跨越午夜),而實際僅 2 分鐘。

實戰:查詢今日異動資料


-- 寫法 1:DATEDIFF(會掃描全表,無法用索引)
SELECT * FROM Orders WHERE DATEDIFF(DAY, OrderDate, GETDATE()) = 0

-- 寫法 2:範圍查詢(SARGable,可用索引)—— 強烈推薦
DECLARE @TodayStart DATETIME = DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0)
DECLARE @TomorrowStart DATETIME = DATEADD(DAY, 1, @TodayStart)
SELECT * FROM Orders WHERE OrderDate >= @TodayStart AND OrderDate < @TomorrowStart

5. DATEPART:取得整數形式的日期部分


SELECT DATEPART(YEAR,   GETDATE())  -- 2024
SELECT DATEPART(MONTH,  GETDATE())  -- 1
SELECT DATEPART(WEEKDAY,GETDATE())  -- 2 (週一=1...視 SET DATEFIRST)
SELECT DATEPART(DAY,    GETDATE())  -- 15
SELECT DAY(GETDATE())               -- 同 DATEPART(DAY,...)
SELECT MONTH(GETDATE())             -- 同 DATEPART(MONTH,...)
SELECT YEAR(GETDATE())              -- 同 DATEPART(YEAR,...)

datepart 間隔單位完整對照表

間隔縮寫說明
yearyy, yyyy年
quarterqq, q季度
monthmm, m月
dayofyeardy, y年間第幾天
daydd, d日
weekww, wk年間第幾週
weekdaydw星期幾
hourhh時
minutemi, n分
secondss, s秒
millisecondms毫秒

常見錯誤與避坑指南

  • WEEKDAY 受 @@DATEFIRST 影響: 預設美式英文環境週日=1,歐式環境週一=1。跨環境程式碼請使用 DATENAME(WEEKDAY,...) 或顯式 SET DATEFIRST 7。
  • DATEDIFF 不等於時間長度: 計算精確時長請用 DATEDIFF(SECOND, start, end) 或 DATEDIFF(MILLISECOND, ...)。
  • 日期字串隱式轉換風險: 永遠使用 ISO 8601 格式 'YYYYMMDD' 或 'YYYY-MM-DDTHH:MM:SS',避免語言/日期格式設定導致解析錯誤。
  • datetime vs datetime2 精度差異: datetime 精度 3.33ms,末位只能是 0/3/7;datetime2 可達 100ns。比較、排序時注意精度截斷問題。

進階組合技:動態日期範圍參數化


-- 近 30 天
DECLARE @End DATETIME2 = SYSUTCDATETIME()
DECLARE @Start DATETIME2 = DATEADD(DAY, -30, @End)

-- 本月迄今 (MTD)
DECLARE @MonthStart DATETIME2 = DATEADD(MONTH, DATEDIFF(MONTH, 0, @End), 0)

-- 上月完整區間
DECLARE @LastMonthStart DATETIME2 = DATEADD(MONTH, -1, @MonthStart)
DECLARE @LastMonthEnd   DATETIME2 = @MonthStart

熟練掌握這四大函數與其組合模式,是寫出高效能、可維護 T-SQL 日期邏輯的關鍵。

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