實作報表或後台統計時,常需要「查詢今天、這一週、這一個月」的資料。本文整理 MySQL 日期查詢的常用寫法,並說明為何建議避免在欄位上使用函數,以利用索引提升效能。
假設欄位 birthday 為 DATE 或 DATETIME 型別:
birthday > '2009-02-03':大於該日(不含當日)birthday >= '2009-02-03':大於等於該日(含當日)birthday < '2009-02-04':小於隔日 00:00:00(等同含當日全天)關鍵原則:盡量用「開區間」WHERE col >= 'start' AND col < 'end',避免對欄位使用 DATE()、TO_DAYS() 等函數,導致索引失效。
-- 利用 CURDATE() 取得當天日期,配合開區間
SELECT * FROM `orders`
WHERE `create_time` >= CURDATE()
AND `create_time` < CURDATE() + INTERVAL 1 DAY;
SELECT * FROM `orders`
WHERE `create_time` >= DATE_SUB(CURDATE(), INTERVAL 6 DAY)
AND `create_time` < CURDATE() + INTERVAL 1 DAY;
SELECT * FROM `orders`
WHERE `create_time` >= DATE_FORMAT(CURDATE(), '%Y-%m-01')
AND `create_time` < DATE_FORMAT(CURDATE(), '%Y-%m-01') + INTERVAL 1 MONTH;
SELECT * FROM `orders`
WHERE `create_time` >= DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 1 MONTH), '%Y-%m-01')
AND `create_time` < DATE_FORMAT(CURDATE(), '%Y-%m-01');
| 函數 | 說明 | 範例 |
|---|---|---|
UNIX_TIMESTAMP() | 目前時間轉 Unix 秒數 | SELECT UNIX_TIMESTAMP(); |
UNIX_TIMESTAMP('2023-01-01 12:00:00') | 指定日期時間轉 Unix 秒數 | SELECT UNIX_TIMESTAMP('2023-01-01 12:00:00'); |
FROM_UNIXTIME(1672574400) | Unix 秒數轉 YYYY-MM-DD HH:MM:SS | SELECT FROM_UNIXTIME(1672574400); |
FROM_UNIXTIME(ts, '%Y-%m-%d') | 自訂格式輸出 | SELECT FROM_UNIXTIME(ts, '%Y-%m-%d'); |
WHERE DATE(create_time) = CURDATE() —— 會導致全表掃描create_time 建立索引,配合開區間查詢掌握這些模式,即可輕鬆應對各類時間維度的統計需求。