萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> 資料庫綜合

SQL Server 精準取得指定月份天數技巧:DATEADD + DAY 組合拳

取得某月天數的核心邏輯:**求下個月第一天,減一天,取 DAY 部分**。本文提供三種常見場景的標準寫法,並解析 DAY() 與 DATEPART(day, ...) 等價性。

核心公式

DAY( DATEADD(month, 1, <目標月第一天>) - 1 )
  • DATEADD(month, 1, ...):推進到下個月第一天。
  • - 1:退回上個月最後一天 (datetime 運算自動處理月份邊界)。
  • DAY(...):擷取日期部分 → 即該月總天數。

三大場景標準寫法

1. 指定年月 (如 2008 年 2 月)

SELECT DAY(CAST('2008-03-01' AS DATETIME) - 1);  -- 29 (2008 為閏年)
-- 或更直觀
SELECT DAY(DATEADD(month, 1, '2008-02-01') - 1);

2. 當月天數

SELECT DAY(DATEADD(month, 1, GETDATE()) - DAY(GETDATE()));
-- 邏輯: 今天 -> 加 1 月 -> 減去今天的日數 -> 得到本月最後一天 -> 取 DAY

**等價簡化** (SQL Server 2012+):

SELECT DAY(EOMONTH(GETDATE()));  -- EOMONTH 直接回傳本月最後一天

3. 上月天數

SELECT DAY(GETDATE() - DAY(GETDATE()));
-- 邏輯: 今天 -> 減去今天的日數 -> 得到上月最後一天 -> 取 DAY

**等價簡化** (SQL Server 2012+):

SELECT DAY(EOMONTH(GETDATE(), -1));

函數等價對照

函數語法回傳型別備註
DAYDAY(date)INTDATEPART(day, date) 同義詞
MONTHMONTH(date)INTDATEPART(month, date) 同義詞
YEARYEAR(date)INTDATEPART(year, date) 同義詞
EOMONTHEOMONTH(start_date [, month_offset])DATESQL 2012+,**首選**,可直接加減月份

效能與可讀性建議

  1. SQL Server 2012+ 專案:直接用 DAY(EOMONTH(...)),**最簡潔、語意最清晰、效能最佳**。
  2. 舊版本 (2008 R2 及以下):使用 DAY(DATEADD(month, 1, ...) - 1) 模式,經過充分測試、無時區/語言相依性。
  3. 避免使用字串操作 (SUBSTRING, CONVERT) 計算天數,效能差且易錯。

應用範例:產生月份日曆表

DECLARE @Year INT = 2024;
WITH Months AS (
    SELECT 1 AS M UNION ALL SELECT M+1 FROM Months WHERE M < 12
)
SELECT
    M AS Month,
    DAY(EOMONTH(DATEFROMPARTS(@Year, M, 1))) AS DaysInMonth
FROM Months
OPTION (MAXRECURSION 12);

掌握「下月 1 號減 1 天」通用邏輯,不再為閏年、大小月邊界條件煩惱。

copyright © 萬盛學電腦網 all rights reserved