MySQL 提供 100+ 內置函數,善用它們能將業務邏輯下推到數據庫層,減少應用層數據傳輸與處理。本文按類別整理高頻函數,附帶語法、參數說明與實戰範例,作為開發與調優的桌面速查手冊。
| 函數 | 說明 | 範例 | 結果 |
|---|---|---|---|
| ABS(x) | 絕對值 | ABS(-3.5) | 3.5 |
| CEIL(x) / CEILING(x) | 向上取整 | CEIL(3.2) | 4 |
| FLOOR(x) | 向下取整 | FLOOR(3.8) | 3 |
| ROUND(x, d) | 四捨五入保留 d 位小數 | ROUND(3.14159, 2) | 3.14 |
| RAND([seed]) | 隨機數 0-1,種子固定則序列固定 | RAND() | 0.123... |
| POWER(x, y) / POW(x, y) | x 的 y 次方 | POWER(2, 3) | 8 |
| SQRT(x) | 平方根 | SQRT(16) | 4 |
| MOD(n, m) / n % m | 取模 | MOD(10, 3) | 1 |
| SIGN(x) | 符號:正負零返回 1/-1/0 | SIGN(-5) | -1 |
| 函數 | 說明 | 範例 | 結果 |
|---|---|---|---|
| LENGTH(str) | 字節長度 | LENGTH('中文') | 6 (utf8mb4) |
| CHAR_LENGTH(str) / CHARACTER_LENGTH(str) | 字符數 | CHAR_LENGTH('中文') | 2 |
| CONCAT(s1, s2, ...) | 拼接,任一 NULL 結果 NULL | CONCAT('a', 'b', NULL) | NULL |
| CONCAT_WS(sep, s1, s2, ...) | 帶分隔符拼接,忽略 NULL | CONCAT_WS('-', 'a', NULL, 'c') | a-c |
| SUBSTRING(str, pos, len) / SUBSTR / MID | 截取子串,pos 從 1 開始,負數倒數 | SUBSTRING('abcdef', 2, 3) | bcd |
| LEFT(str, len) / RIGHT(str, len) | 左/右截取 | LEFT('abcdef', 3) | abc |
| TRIM([BOTH|LEADING|TRAILING] [remstr] FROM str) | 去除首尾空格或指定字符 | TRIM(' abc ') | abc |
| LTRIM(str) / RTRIM(str) | 去左/右空格 | LTRIM(' abc') | abc |
| REPLACE(str, from_str, to_str) | 替換所有匹配 | REPLACE('a b c', ' ', '_') | a_b_c |
| INSERT(str, pos, len, newstr) | pos 位置起 len 長度替換為 newstr | INSERT('abcdef', 2, 3, 'XYZ') | aXYZef |
| UPPER(str) / UCASE(str) | 轉大寫 | UPPER('abc') | ABC |
| LOWER(str) / LCASE(str) | 轉小寫 | LOWER('ABC') | abc |
| LPAD(str, len, padstr) / RPAD(str, len, padstr) | 左/右填充至指定長度 | LPAD('123', 6, '0') | 000123 |
| REPEAT(str, count) | 重複字符串 | REPEAT('ab', 3) | ababab |
| REVERSE(str) | 反轉字符串 | REVERSE('abc') | cba |
| LOCATE(substr, str, [pos]) / POSITION(substr IN str) / INSTR(str, substr) | 查找子串首次出現位置(1-based),不存在返回 0 | LOCATE('c', 'abcdef') | 3 |
| STRCMP(s1, s2) | 比較:s1>s2→1, =→0, <→-1 | STRCMP('b', 'a') | 1 |
| FIELD(str, s1, s2, ...) | 返回 str 在列表中首次匹配位置(1-based) | FIELD('b', 'a', 'b', 'c') | 2 |
| FIND_IN_SET(str, strlist) | strlist 為逗號分隔字符串,返回位置 | FIND_IN_SET('b', 'a,b,c') | 2 |
| ELT(n, s1, s2, ...) | 返回第 n 個字符串 | ELT(2, 'a', 'b', 'c') | b |
| MAKE_SET(bits, s1, s2, ...) | bits 二進制位為 1 對應字符串拼接 | MAKE_SET(5, 'a', 'b', 'c') -- 5=101b | a,c |
| SPACE(n) | 生成 n 個空格 | CONCAT('a', SPACE(3), 'b') | a b |
| QUOTE(str) | 生成可用於 SQL 的帶引號字符串 | QUOTE("Don't") | 'Don\'t' |
| 函數 | 說明 | 範例 | 結果 |
|---|---|---|---|
| NOW() / SYSDATE() / CURRENT_TIMESTAMP() | 當前日期時間(微秒精度 5.6.4+) | NOW() | 2023-10-15 14:30:45 |
| CURDATE() / CURRENT_DATE() | 當前日期 | CURDATE() | 2023-10-15 |
| CURTIME() / CURRENT_TIME() | 當前時間 | CURTIME() | 14:30:45 |
| UNIX_TIMESTAMP([date]) | 日期轉 Unix 時間戳(秒) | UNIX_TIMESTAMP('2023-10-15') | 1697342400 |
| FROM_UNIXTIME(unix_ts) | 時間戳轉日期時間 | FROM_UNIXTIME(1697342400) | 2023-10-15 00:00:00 |
| DATE_FORMAT(date, format) | 格式化輸出 | DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i') | 2023-10-15 14:30 |
| STR_TO_DATE(str, format) | 字符串解析為日期 | STR_TO_DATE('15/10/2023', '%d/%m/%Y') | 2023-10-15 |
| DATE_ADD(date, INTERVAL expr unit) / ADDDATE | 日期加減 | DATE_ADD(NOW(), INTERVAL 1 DAY) | 明天這時 |
| DATE_SUB(date, INTERVAL expr unit) / SUBDATE | 日期減去 | DATE_SUB(NOW(), INTERVAL 1 MONTH) | 上月這時 |
| DATEDIFF(date1, date2) | 日期差天數 (date1-date2) | DATEDIFF('2023-10-15', '2023-10-10') | 5 |
| TIMESTAMPDIFF(unit, dt1, dt2) | 精確時間差(支持 MICROSECOND..YEAR) | TIMESTAMPDIFF(SECOND, '2023-10-15 10:00', '2023-10-15 12:00') | 7200 |
| YEAR/MONTH/DAY/HOUR/MINUTE/SECOND(date) | 提取對應部分 | MONTH(NOW()) | 10 |
| QUARTER(date) | 季度 1-4 | QUARTER(NOW()) | 4 |
| WEEK(date, [mode]) / WEEKOFYEAR(date) | 年內第幾周 | WEEK(NOW()) | 41 |
| DAYOFWEEK(date) / WEEKDAY(date) | 星期:前者 1=周日,後者 0=周一 | WEEKDAY('2023-10-15') | 6 (周日) |
| DAYNAME(date) / MONTHNAME(date) | 英文星期/月份名 | DAYNAME(NOW()) | Sunday |
| DAYOFYEAR(date) / DAYOFMONTH(date) | 年內/月內第幾天 | DAYOFYEAR(NOW()) | 288 |
| LAST_DAY(date) | 該月最後一天日期 | LAST_DAY('2023-02-10') | 2023-02-28 |
| MAKEDATE(year, dayofyear) / MAKETIME(h, m, s) | 構造日期/時間 | MAKEDATE(2023, 100) | 2023-04-10 |
| PERIOD_ADD(period, n) / PERIOD_DIFF(p1, p2) | 年月期間運算 (YYYYMM) | PERIOD_ADD(202310, 3) | 202401 |
| EXTRACT(unit FROM date) | 標準 SQL 提取部分 | EXTRACT(MONTH FROM NOW()) | 10 |
| TIME_TO_SEC(time) / SEC_TO_TIME(seconds) | 時間⇔秒數轉換 | TIME_TO_SEC('01:30:00') | 5400 |
DATE_FORMAT 常用格式符:%Y 四位年、%m 兩位月、%d 兩位日、%H 24制時、%i 分、%s 秒、%f 微秒、%W 星期名、%M 月份名。
| 函數 | 語法 | 說明 | 範例 |
|---|---|---|---|
| IF | IF(expr, true_val, false_val) | expr 為真返回 true_val,否則 false_val | IF(score>=60, '及格', '不及格') |
| IFNULL | IFNULL(expr1, expr2) | expr1 非 NULL 返回 expr1,否則 expr2 | IFNULL(bonus, 0) |
| COALESCE | COALESCE(v1, v2, ..., vn) | 返回第一個非 NULL 值(標準 SQL,推薦) | COALESCE(phone, email, '無聯繫方式') |
| CASE (簡單) | CASE expr WHEN v1 THEN r1 [WHEN v2 THEN r2...] [ELSE rn] END | expr 與值比較 | CASE grade WHEN 'A' THEN '優' WHEN 'B' THEN '良' ELSE '其他' END |
| CASE (搜索) | CASE WHEN cond1 THEN r1 [WHEN cond2 THEN r2...] [ELSE rn] END | 條件表達式判斷 | CASE WHEN score>=90 THEN 'A' WHEN score>=80 THEN 'B' ELSE 'C' END |
| NULLIF | NULLIF(expr1, expr2) | 相等返回 NULL,否則 expr1 | NULLIF(rate, 0) 避免除零 |
| 函數 | 說明 |
|---|---|
| VERSION() | 服務器版本號 |
| CONNECTION_ID() | 當前連接 ID(線程 ID) |
| DATABASE() / SCHEMA() | 當前默認數據庫 |
| USER() / SYSTEM_USER() / SESSION_USER() | 客戶端聲明的用戶@主機 |
| CURRENT_USER() | 服務器認證後的真實用戶@主機(權限匹配者) |
| CHARSET(str) / COLLATION(str) | 字符串字符集/校驗規則 |
| LAST_INSERT_ID() | 上一條 INSERT/UPDATE 生成的自增 ID(連接級隔離) |
| ROW_COUNT() | 上一條 DML 影響行數 |
| FOUND_ROWS() | 配合 SQL_CALC_FOUND_ROWS 獲取無 LIMIT 總行數 |
| BENCHMARK(count, expr) | 重複執行 expr count 次,測試性能 |
| SLEEP(seconds) | 休眠秒數,測試超時/鎖等待 |
| 函數 | 說明 | 備註 |
|---|---|---|
| MD5(str) | 128 位雜湊,32 字符十六進制 | 不可逆,校驗完整性、非核心密碼 |
| SHA1(str) / SHA(str) | 160 位雜湊,40 字符 | 比 MD5 強,同不可逆 |
| SHA2(str, hash_len) | SHA-2 族:224/256/384/512 | 推薦 SHA2(str, 256) |
| PASSWORD(str) | MySQL 內部密碼雜湊(5.7.6+ 移除) | 勿用於應用層密碼存儲 |
| AES_ENCRYPT(str, key) / AES_DECRYPT(crypt, key) | AES 對稱加解密,ECB 模式 | key 長度 16/24/32 字節 |
| DES_ENCRYPT / DES_DECRYPT | DES 加解密(已棄用) | 不安全,勿用 |
| ENCODE(str, pass) / DECODE(crypt, pass) | 舊式弱加密(8.0 移除) | 不安全,勿用 |
| COMPRESS(str) / UNCOMPRESS(str) | zlib 壓縮/解壓,返回 BLOB | 存儲大文本/JSON 節省空間 |
| UNCOMPRESSED_LENGTH(comp_str) | 壓縮前長度 |
密碼存儲最佳實踐:應用層使用
bcrypt、argon2、PBKDF2(如 PHPpassword_hash()、JavaBCrypt),數據庫僅存儲雜湊值,不要依賴 MySQL 內置加密函數。
| 函數 | 說明 | 範例 |
|---|---|---|
| FORMAT(x, n, [locale]) | 數字格式化:千分位分隔、保留 n 位小數 | FORMAT(1234567.89, 2) → '1,234,567.89' |
| INET_ATON(ip) / INET_NTOA(num) | IPv4 地址⇔無符號整數互轉 | INET_ATON('192.168.1.1') → 3232235777 |
| INET6_ATON(ip) / INET6_NTOA(bin) | IPv6 地址⇔二進制字符串互轉 (5.6.3+) | 支持 IPv4 映射 IPv6 |
| GET_LOCK(name, timeout) / RELEASE_LOCK(name) / IS_FREE_LOCK(name) / IS_USED_LOCK(name) | 用戶級命名鎖(應用層分布式鎖簡易實現) | GET_LOCK('order_123', 10) 獲取鎖 |
| UUID() / UUID_SHORT() | 生成 UUID(標準 36 字符 / 64 位整數) | UUID_SHORT() 適合分布式 ID 生成 |
| DEFAULT(col) | 獲取列默認值 (8.0+) | INSERT INTO t (c) VALUES (DEFAULT(c)) |
| JSON_EXTRACT / -> / ->> / JSON_SET / JSON_ARRAY / JSON_OBJECT 等 | JSON 類型操作函數族 (5.7+) | 詳見 JSON 專題 |
WHERE DATE(create_time)=... → 索引失效。改為範圍查詢。IFNULL/COALESCE 顯式處理,COUNT(col) vs COUNT(*) 區分。TIMESTAMP 自動轉換,DATETIME 不轉換。MySQL 函數庫豐富實用,**字符串處理、日期運算、條件表達、類型轉換** 是高頻核心。將常用函數語法內化,配合「列上無函數、類型顯式匹配、NULL 顯式處理」三原則,即能寫出既簡潔又高性能的 SQL 表達式。