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

SQL Server 日期時間處理完全指南:月份、週期與常用查詢技巧

     編輯:關於SqlServer

    前言

    在 SQL Server 開發與維護中,日期時間運算是極高頻的需求。無論是取得本月首尾日、本週一、季度邊界,還是依月、週、季篩選資料,掌握標準寫法能大幅提升效能與可維護性。本文整理 14 類常見場景,附上可直接複製的 T-SQL 範例,並說明關鍵函數原理,助你快速套用專案。

    一、月份邊界計算

    1. 本月第一天

    -- 方法 1:日期差運算(效能最佳)
    SELECT DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0);
    
    -- 方法 2:字串轉換(較直觀)
    SELECT CONVERT(datetime, CONVERT(varchar(8), GETDATE(), 120) + '01', 120);

    2. 本月最後一天

    -- 方法 1:下月 1 日減 1 天
    SELECT DATEADD(day, -1, CONVERT(datetime, CONVERT(varchar(8), DATEADD(month, 1, GETDATE()), 120) + '01', 120));
    
    -- 方法 2:毫秒精度避免四捨五入問題
    SELECT DATEADD(ms, -3, DATEADD(month, DATEDIFF(month, 0, GETDATE()) + 1, 0));

    3. 上個月最後一天

    SELECT DATEADD(ms, -3, DATEADD(month, DATEDIFF(month, 0, GETDATE()), 0));

    二、週期與年度邊界

    4. 本月第一個星期一

    SELECT DATEADD(week, DATEDIFF(week, 0, DATEADD(day, 6 - DATEPART(day, GETDATE()), GETDATE())), 0);

    5. 本年第一天 / 6. 本年最後一天 / 7. 去年最後一天

    -- 本年第一天
    SELECT DATEADD(year, DATEDIFF(year, 0, GETDATE()), 0);
    
    -- 本年最後一天
    SELECT DATEADD(ms, -3, DATEADD(year, DATEDIFF(year, 0, GETDATE()) + 1, 0));
    
    -- 去年最後一天
    SELECT DATEADD(ms, -3, DATEADD(year, DATEDIFF(year, 0, GETDATE()), 0));

    三、季度與週邊界

    8. 本季度第一天

    SELECT DATEADD(quarter, DATEDIFF(quarter, 0, GETDATE()), 0);

    9. 本週星期一(以週一為週起始)

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

    四、依時間範圍查詢資料

    建議使用「半開半閉區間」寫法(WHERE dt >= @start AND dt < @end),可用索引且避免函數導致掃描。下列為傳統 DATEPART 寫法,僅供參考:

    10. 查詢本月記錄

    SELECT * FROM tableName
    WHERE DATEPART(month, theDate) = DATEPART(month, GETDATE())
      AND DATEPART(year, theDate) = DATEPART(year, GETDATE());

    11. 查詢本週記錄

    SELECT * FROM tableName
    WHERE DATEPART(week, theDate) = DATEPART(week, GETDATE())
      AND DATEPART(year, theDate) = DATEPART(year, GETDATE());

    12. 查詢本季記錄

    SELECT * FROM tableName
    WHERE DATEPART(quarter, theDate) = DATEPART(quarter, GETDATE())
      AND DATEPART(year, theDate) = DATEPART(year, GETDATE());

    五、實用工具函數

    13. 取得當月總天數

    -- 方法 1:簡潔
    SELECT DATEDIFF(day, GETDATE(), DATEADD(month, 1, GETDATE()));
    
    -- 方法 2:相容舊版
    SELECT DATEDIFF(day,
        DATEADD(month, DATEDIFF(month, '', GETDATE()), ''),
        DATEADD(month, DATEDIFF(month, '', GETDATE()), '1900-02-01'));

    14. 取得今天是星期幾

    SELECT DATENAME(weekday, GETDATE()); -- 回傳 'Monday'、'星期一' 等(視語系)

    核心原理速查

    • DATEDIFF / DATEADD 組合:以「基準日 0 (1900-01-01)」為錨點,先算間隔再加回,效能最佳且無語系相依。
    • 毫秒扣除 (-3ms):避免 DATETIME 精度 3.33ms 導致的午夜歸屬問題。
    • 半開半閉區間:WHERE dt >= '2024-01-01' AND dt < '2024-02-01' 可用索引,優於函數包裹欄位。

    結語

    將上述片段收藏為程式碼片段或建立為資料庫函數,即可在專案中快速重用。記得根據資料型別(DATE、DATETIME2、DATETIMEOFFSET)微調精度,即可應對各種版本與雲端環境。

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