在 SQL Server 中,若要篩選出「最近 30 天」的資料,最直觀的寫法是利用 DATEDIFF 函數計算日期差異:
SELECT *
FROM YourTable
WHERE DATEDIFF(day, DateColumn, GETDATE()) < 30;
說明:
day:指定比較單位為「天」。DateColumn:資料表中儲存日期時間的欄位名稱。GETDATE():取得資料庫伺服器的當前日期時間。< 30:保留差異小於 30 天的記錄(即最近 30 天內)。上述寫法雖然簡潔,但 會導致索引無法被使用(Non-SARGable),因為函數作用在欄位上,資料庫引擎必須掃描全表計算差值。資料量大時效能會明顯下降。
SELECT *
FROM YourTable
WHERE DateColumn >= DATEADD(day, -30, GETDATE());
這樣寫法可直接利用 DateColumn 上的索引進行範圍查詢(Index Seek),效能大幅提升。
若需精確到「前 30 天整天」,不包含今日目前時間之後的資料:
WHERE DateColumn >= DATEADD(day, -30, CAST(GETDATE() AS DATE))
AND DateColumn < CAST(GETDATE() AS DATE);
若伺服器與應用程式時區不同,建議統一使用 GETUTCDATE() 並確保欄位儲存 UTC 時間:
WHERE DateColumn >= DATEADD(day, -30, GETUTCDATE());
確保 DateColumn 型別為 DATE、DATETIME 或 DATETIME2,避免字串比較導致隱含轉換。
| 寫法 | 可用索引 | 適用場景 |
|---|---|---|
DATEDIFF(day, col, GETDATE()) < 30 | ❌ 否 | 資料量小、臨時查詢 |
col >= DATEADD(day, -30, GETDATE()) | ✅ 是 | 生產環境、大量資料、需高效能 |
最佳實務: 永遠優先使用「欄位直接比較」而非「函數包裹欄位」的寫法,並為常用篩選欄位建立索引。