MySQL 常用內建函數完整指南
MySQL 提供豐富的內建函數,善用它們能大幅簡化 SQL 撰寫並提升效能。本文整理實務上最常用的四大類函數,附帶範例與注意事項。
一、日期時間函數
| 函數 | 說明 | 範例 | 結果 |
NOW() | 目前日期時間 | SELECT NOW(); | 2024-05-20 14:30:00 |
CURDATE() | 目前日期 | SELECT CURDATE(); | 2024-05-20 |
CURTIME() | 目前時間 | SELECT CURTIME(); | 14:30:00 |
UNIX_TIMESTAMP() | 轉 Unix 時間戳(秒) | SELECT UNIX_TIMESTAMP('2024-01-01'); | 1704067200 |
FROM_UNIXTIME() | 時間戳轉日期時間 | SELECT FROM_UNIXTIME(1704067200); | 2024-01-01 00:00:00 |
DATE_FORMAT() | 自訂格式化輸出 | SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i'); | 2024-05-20 14:30 |
DATE_ADD() | 日期加減運算 | SELECT DATE_ADD(NOW(), INTERVAL 1 MONTH); | 一個月後 |
DATEDIFF() | 兩日期相差天數 | SELECT DATEDIFF('2024-12-31', NOW()); | 正整數 |
YEAR(), MONTH(), DAY(), HOUR(), MINUTE(), SECOND() | 擷取單一元件 | SELECT MONTH(NOW()); | 5 |
提醒: UNIX_TIMESTAMP 受 32 位元限制,最大支援至 2038-01-19(Year 2038 Problem),長期專案建議改用 BIGINT 儲存毫秒級時間戳。
二、字串函數
| 函數 | 說明 | 範例 | 結果 |
CONCAT() | 串接字串(任一參數為 NULL 則回傳 NULL) | SELECT CONCAT('My', 'SQL'); | MySQL |
CONCAT_WS() | 指定分隔符串接(自動忽略 NULL) | SELECT CONCAT_WS('-', '2024', '05', '20'); | 2024-05-20 |
SUBSTRING(), SUBSTR() | 擷取子字串 | SELECT SUBSTRING('MySQL', 3); | SQL |
LEFT(), RIGHT() | 取左/右 N 字元 | SELECT LEFT('MySQL', 2); | My |
REPLACE() | 字串替換 | SELECT REPLACE('MySQL', 'My', 'Your'); | YourSQL |
TRIM(), LTRIM(), RTRIM() | 去除前後/左/右空白 | SELECT TRIM(' test '); | test |
UPPER(), LOWER() | 大小寫轉換 | SELECT UPPER('mysql'); | MYSQL |
LPAD(), RPAD() | 左/右填充至指定長度 | SELECT LPAD('5', 3, '0'); | 005 |
REPEAT() | 重複字串 | SELECT REPEAT('ab', 3); | ababab |
STRCMP() | 字串比較(-1/0/1) | SELECT STRCMP('a', 'b'); | -1 |
三、數值函數
| 函數 | 說明 | 範例 | 結果 |
ABS() | 絕對值 | SELECT ABS(-1.5); | 1.5 |
CEIL(), CEILING() | 無條件進位 | SELECT CEIL(1.1); | 2 |
FLOOR() | 無條件捨去 | SELECT FLOOR(1.9); | 1 |
ROUND() | 四捨五入(可指定小數位) | SELECT ROUND(1.235, 2); | 1.24 |
TRUNCATE() | 直接截斷(不四捨五入) | SELECT TRUNCATE(1.235, 2); | 1.23 |
MOD(), % | 取餘數 | SELECT MOD(10, 3); | 1 |
RAND() | 0~1 隨機數 | SELECT FLOOR(RAND() * 100); | 0~99 整數 |
BIN() | 轉二進位字串 | SELECT BIN(10); | 1010 |
四、流程控制函數
-- IF(條件, 真值, 假值)
SELECT IF(score >= 60, '及格', '不及格') FROM exam;
-- IFNULL(值, 預設值) -- 僅判斷 NULL
SELECT IFNULL(bonus, 0) FROM salary;
-- CASE WHEN ... THEN ... ELSE ... END (通用)
SELECT CASE
WHEN salary < 30000 THEN '低薪'
WHEN salary < 60000 THEN '中薪'
ELSE '高薪'
END FROM employee;
-- CASE 欄位 WHEN 值 THEN ... END (等值比對)
SELECT CASE dept_id
WHEN 1 THEN '研發部'
WHEN 2 THEN '業務部'
ELSE '其他'
END FROM employee;
五、其他實用資訊函數
DATABASE():目前資料庫名
VERSION():MySQL 版本
USER()、CURRENT_USER():連線使用者
INET_ATON() / INET_NTOA():IP 字串與整數互轉
MD5(), SHA1(), SHA2():雜湊函數
PASSWORD():MySQL 內部加密(不建議應用層使用)
效能小撇步
- 避免在
WHERE 條件欄位上套用函數(如 WHERE DATE(create_time) = '2024-05-20'),會導致索引失效,改用範圍查詢 WHERE create_time >= '2024-05-20' AND create_time < '2024-05-21'。
- 大量資料處理時,考慮在應用層完成字串拼裝、格式化,減少資料庫 CPU 負載。
- 隨機排序
ORDER BY RAND() 在大表極慢,改用應用層抽樣或 WHERE id >= (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM t))) 等技巧。