首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL 字串型數字排序與日期格式化查詢實戰

     編輯:MySQL 綜合教學

MySQL 字串型數字排序與日期格式化查詢實戰

資料庫設計不當導致數字存為 VARCHAR、日期存為字串,查詢排序時出現「10 排在 2 前面」、「無法按月日篩選生日」等問題。本文提供解決方案與最佳實踐。

問題 1:VARCHAR 數字排序錯誤

-- 資料:'1', '2', '10', '20', '100'
SELECT `id` FROM `t` ORDER BY `id`;  -- 字串排序:1, 10, 100, 2, 20 ❌

-- 解決 1:隱式轉換(利用數學運算強制轉數值)
SELECT `id` FROM `t` ORDER BY `id` + 0;           -- 1, 2, 10, 20, 100 ✅
SELECT `id` FROM `t` ORDER BY CAST(`id` AS UNSIGNED);  -- 標準寫法 ✅
SELECT `id` FROM `t` ORDER BY `id` * 1;           -- 同理 ✅

-- 解決 2:左填充固定長度(不改動資料,純排序)
SELECT `id` FROM `t` ORDER BY LPAD(`id`, 10, '0');  -- 0000000001, 0000000002... ✅

問題 2:生日月日範圍查詢(忽略年份)

-- 需求:查詢 06-03 到 07-08 之間過生日的會員
-- birthday 欄位為 DATE 或 DATETIME

-- 解決:DATE_FORMAT 擷取月日比較
SELECT * FROM `member` 
WHERE DATE_FORMAT(`birthday`, '%m-%d') BETWEEN '06-03' AND '07-08';

-- 注意:跨年範圍(如 12-20 到 01-10)需拆兩段
SELECT * FROM `member` 
WHERE DATE_FORMAT(`birthday`, '%m-%d') >= '12-20' 
   OR DATE_FORMAT(`birthday`, '%m-%d') <= '01-10';

MySQL 日期時間函數速查表

函數說明範例結果
DATE_FORMAT(date, fmt)自訂格式化DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i')2024-05-20 14:30
DAYOFWEEK(date)星期索引 (1=週日)DAYOFWEEK('2024-05-20')2
WEEKDAY(date)星期索引 (0=週一)WEEKDAY('2024-05-20')0
DAYOFMONTH(date)月份中的天DAYOFMONTH('2024-05-20')20
DAYOFYEAR(date)年中的天數DAYOFYEAR('2024-05-20')141
MONTH(date)月份 (1-12)MONTH('2024-05-20')5
DAYNAME(date)星期名稱DAYNAME('2024-05-20')Monday
MONTHNAME(date)月份名稱MONTHNAME('2024-05-20')May
QUARTER(date)季度 (1-4)QUARTER('2024-05-20')2
WEEK(date, mode)週數,mode 控制週起始日WEEK('2024-05-20', 1)21
YEAR(date)年份YEAR('2024-05-20')2024
HOUR(time)小時 (0-23)HOUR('14:30:00')14
MINUTE(time)分鐘MINUTE('14:30:00')30
SECOND(time)秒SECOND('14:30:00')0
DATE_ADD(date, INTERVAL expr unit)日期加減DATE_ADD(NOW(), INTERVAL 1 MONTH)一個月後
DATEDIFF(date1, date2)天數差DATEDIFF('2024-12-31', NOW())正整數
TO_DAYS(date)從 Year 0 起的天數TO_DAYS('2024-05-20')738987
FROM_DAYS(days)天數轉日期FROM_DAYS(738987)2024-05-20
UNIX_TIMESTAMP(date)轉 Unix 時間戳UNIX_TIMESTAMP('2024-05-20')1716172800
FROM_UNIXTIME(ts)時間戳轉日期FROM_UNIXTIME(1716172800)2024-05-20 00:00:00
SEC_TO_TIME(sec)秒數轉時分秒SEC_TO_TIME(3661)01:01:01
TIME_TO_SEC(time)時分秒轉秒數TIME_TO_SEC('01:01:01')3661

DATE_FORMAT 格式符號速查

符號含義範例
%Y4 位數年2024
%y2 位數年24
%m月份 (01-12)05
%c月份 (1-12)5
%d日期 (01-31)20
%e日期 (1-31)20
%H小時 24制 (00-23)14
%h小時 12制 (01-12)02
%i分鐘 (00-59)30
%s秒 (00-59)00
%W星期全名Monday
%a星期縮寫Mon
%M月份全名May
%b月份縮寫May
%D帶後綴的日期20th
%r12制時間02:30:00 PM
%T24制時間14:30:00

效能提醒

  • WHERE DATE_FORMAT(col, ...) = ... **無法使用索引**,大表會全掃。
  • 優化:建立虛擬欄位/生成欄位(8.0+)ALTER TABLE t ADD month_day VARCHAR(5) GENERATED ALWAYS AS (DATE_FORMAT(birthday, '%m-%d')) STORED, ADD INDEX idx_month_day (month_day);
  • 或應用層預計算月日存入獨立欄位 birth_month_day CHAR(5)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved