萬盛學電腦網

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

MySQL DATE 類型使用完全指南:格式、比較、寬鬆解析與陷阱

標準格式與輸入寬鬆度

標準格式:'YYYY-MM-DD' (如 '2024-12-31')。

MySQL 接受「寬鬆格式」:任何標點作為分隔符,甚至無分隔符:

'2024-12-31'  '2024/12/31'  '2024.12.31'  '2024 12 31'  '20241231'
'24-12-31'    '24#12#31'    '2024#12#31'  -- 兩位數年份 2000-2069 窗口

比較運算的隱式轉換規則

比較場景轉換方式說明
日期欄位 vs 常量字串字串 → 長整數 (YYYYMMDD)快速比較,支援寬鬆格式
日期欄位 vs 日期欄位字串比較逐字符比較,較慢
日期欄位 vs 表達式字串比較如 WHERE dt > DATE_SUB(NOW(), INTERVAL 1 DAY)
IN / STRCMP()字串比較不走數值快速路徑

安全比較最佳實踐

-- 1. 統一用標準格式字串常量
WHERE dt >= '2024-01-01' AND dt < '2024-02-01'

-- 2. 日期函數生成邊界
WHERE dt >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)

-- 3. 避免函數包裹索引欄
-- 慢:WHERE DATE(dt) = '2024-01-01'
-- 快:WHERE dt >= '2024-01-01' AND dt < '2024-01-02'

-- 4. 顯式轉換消除歧義
WHERE dt = CAST('2024-01-01' AS DATE)

特殊值 '0000-00-00'

  • 可儲存/查詢,代表「零日期」
  • MyODBC 2.50.12+ 自動轉為 NULL
  • 嚴格模式 (NO_ZERO_DATE) 下禁止寫入
  • DATE('0000-00-00') 返回 NULL

數值環境下的自動轉換

INSERT INTO t (dt) VALUES (20240101);       -- 數值 → 日期
INSERT INTO t (dt) VALUES ('20240101');     -- 無分隔符字串
SELECT dt + 0 FROM t;                       -- 日期 → 數值 20240101
SELECT MOD(dt, 100) FROM t;                 -- 取日部分 → 1

時區與 DATE/TIMESTAMP 差異

  • DATE:無時區概念,存什麼讀什麼
  • TIMESTAMP:存儲 UTC,讀取轉換為會話時區
  • 跨時區應用:統一用 TIMESTAMP 或應用層處理 DATE 時區

常見錯誤避坑

  1. WHERE dt = '2024-1-1' (月/日未補零) → 依賴寬鬆解析,建議統一 DATE_FORMAT 或應用層格式化
  2. BETWEEN '2024-01-01' AND '2024-01-31' 包含 31 日 23:59:59,若欄位為 DATETIME 會漏掉當天資料 → 用半開區間 dt >= '2024-01-01' AND dt < '2024-02-01'
  3. 隱式轉換導致索引失效:WHERE DATE(dt) = ...、WHERE YEAR(dt) = 2024
copyright © 萬盛學電腦網 all rights reserved