業務中常需「查找距離目前 N 天/月/年的資料」,例如「找出 30 年內的員工入職記錄」。MySQL 提供 TIMESTAMPDIFF() 函數與直接日期比較兩種主流寫法,本文透過實測對比其用法與適用場景。
假設資料表 testtable 包含 date 欄位 (型別為 DATE/DATETIME 或 VARCHAR),需查詢 date 與目前時間差 小於 30 年 的記錄。
SELECT * FROM testtable
WHERE TIMESTAMPDIFF(YEAR, `date`, NOW()) < 30;
date 為未來時間,結果為負數,仍滿足 < 30,需視業務決定是否需加 AND `date` <= NOW()。SELECT * FROM testtable
WHERE `date` > '1994-01-01'; -- 假設今年 2024 年,30 年前為 1994
date 欄位為標準日期型別 (DATE/DATETIME/TIMESTAMP),VARCHAR 存儲非標準格式可能比較錯誤。| 維度 | TIMESTAMPDIFF() | 直接比較 |
|---|---|---|
| 索引利用 | ❌ 導致全表掃描 | ✅ 可用索引 Range Scan |
| 型別兼容 | ✅ 支援 VARCHAR 隱式轉換 | ⚠ 嚴格要求日期型別 |
| 語義清晰度 | ✅ 極高 | ⚠ 需註釋說明閾值來源 |
| 適用場景 | 中小表、臨時查詢、VARCHAR 日期欄位 | 大表高頻查詢、標準日期型別欄位 |
WHERE date_col > 'YYYY-MM-DD' 並確保欄位有索引。TIMESTAMPDIFF(),省去清洗成本。TIMESTAMPDIFF 場景,可建立函數索引 (MySQL 8.0+):ALTER TABLE testtable ADD INDEX idx_year_diff ((TIMESTAMPDIFF(YEAR, `date`, NOW()))); (需注意 NOW() 非確定性函數,實際建議建立虛擬欄位 + 索引)。補充: 若需「恰好 30 年前」或「30 年前含當天」,請精確調整比較運算子 (<=, >=) 並考慮時區影響。