表 Meeting 有 PublishTime DATETIME 列(格式 yyyy-mm-dd hh:mm:ss)。前端傳入參數 @PublishTime = '2004-12-01'(僅日期),直接 WHERE PublishTime = @PublishTime 永遠匹配不到,因為時間成分不為 00:00:00。
-- SQL Server / Sybase 語法
SELECT *
FROM Meeting
WHERE CONVERT(VARCHAR(10), PublishTime, 121) = @PublishTime;
VARCHAR(10):目標長度 10,恰好容納 yyyy-mm-dd。121:ODBC 標準格式 yyyy-mm-dd hh:mi:ss.mmm(含毫秒),截取前 10 字符即日期。| Style | 輸出示例 | 說明 |
|---|---|---|
| 101 | mm/dd/yyyy | 美式 |
| 102 | yyyy.mm.dd | ANSI |
| 103 | dd/mm/yyyy | 英式 |
| 120 | yyyy-mm-dd hh:mi:ss | ODBC 無毫秒 |
| 121 | yyyy-mm-dd hh:mi:ss.mmm | ODBC 有毫秒(推薦) |
| 126 | yyyy-mm-ddThh:mi:ss.mmm | ISO8601 |
-- MySQL 使用 DATE() 函數或 CAST
SELECT * FROM Meeting WHERE DATE(PublishTime) = @PublishTime;
-- 或
SELECT * FROM Meeting WHERE CAST(PublishTime AS DATE) = @PublishTime;
-- 索引友好寫法(避免函數殺索引):
SELECT * FROM Meeting
WHERE PublishTime >= @PublishTime
AND PublishTime < DATE_ADD(@PublishTime, INTERVAL 1 DAY);
-- TRUNC 截取日期
SELECT * FROM Meeting WHERE TRUNC(PublishTime) = TO_DATE(@PublishTime, 'YYYY-MM-DD');
-- 索引友好:
SELECT * FROM Meeting
WHERE PublishTime >= TO_DATE(@PublishTime, 'YYYY-MM-DD')
AND PublishTime < TO_DATE(@PublishTime, 'YYYY-MM-DD') + 1;
SELECT * FROM Meeting WHERE PublishTime::date = @PublishTime::date;
-- 索引友好:
SELECT * FROM Meeting
WHERE PublishTime >= @PublishTime::date
AND PublishTime < (@PublishTime::date + INTERVAL '1 day');
WHERE CONVERT(...)=@param 導致全表掃描,無法利用 PublishTime 索引。推薦範圍查詢:
DECLARE @Date DATE = '2004-12-01';
SELECT * FROM Meeting
WHERE PublishTime >= @Date
AND PublishTime < DATEADD(DAY, 1, @Date);
SEEK。日期維度查詢的核心是「去除時間成分」。SQL Server 用 CONVERT(VARCHAR(10), col, 121) 簡單直觀,但生產環境務必改寫為範圍查詢以利用索引。MySQL/Oracle/PostgreSQL 均有對應函數(DATE()/TRUNC()/::date),同樣遵循「函數轉換易讀,範圍查詢快」原則。