統計報表常需按年、月、日分組,但資料欄位精確到秒。以下兩種方法各有優勢。
-- 取得「年-月-日 00:00:00」日期時間值
CAST(
STR(YEAR(GETDATE())) + '/' +
STR(MONTH(GETDATE())) + '/' +
STR(DAY(GETDATE()))
AS DATETIME)
-- 僅需年月
CAST(
STR(YEAR(GETDATE())) + '/' +
STR(MONTH(GETDATE())) + '/01'
AS DATETIME)
優點:邏輯直觀,易讀。
缺點:隱含字串→日期轉換受語言/地區設定影響,跨環境可能失效;性能略低。
-- 取得「本月第一天 00:00:00」
DATEADD(month, DATEDIFF(month, 0, ColTime), 0)
-- 取得「今天零點」
DATEADD(day, DATEDIFF(day, 0, ColTime), 0)
-- 取得「本年第一天」
DATEADD(year, DATEDIFF(year, 0, ColTime), 0)
核心原理:DATEDIFF(interval, 0, ColTime) 計算基準日 1900-01-01 到目標日期的間隔數,再用 DATEADD 加回基準日,直接得到該間隔的「起始邊界」。
優勢:
DATETIME,可直接參與索引範圍查詢(SARGable)。報表分組查詢 推薦方法二,配合 GROUP BY DATEADD(month, DATEDIFF(month, 0, create_time), 0) 既高效又能利用索引。
前端顯示格式化 交由應用層或 CONVERT/FORMAT 處理,資料庫只負責邊界計算。