MySQL: MySQL内置函数大全与实战应用

最后更新:2026-08-26

函数是 SQL 的瑞士军刀——数据转换、格式化、计算都靠它。

本课系统讲解 MySQL 最常用的内置函数。

100%
graph TB
    A[MySQL 内置函数] --> B[数学函数<br/>ROUND/CEIL/FLOOR/RAND]
    A --> C[字符串函数<br/>CONCAT/LENGTH/SUBSTRING]
    A --> D[日期函数<br/>NOW/DATE_FORMAT/DATEDIFF]
    A --> E[条件函数<br/>IF/IFNULL/CASE]
    A --> F[聚合函数<br/>COUNT/SUM/AVG/MAX/MIN]
    A --> G[类型转换<br/>CAST/CONVERT]

1. 你将学到


2. 数据清洗的真实故事

(1) 痛点:数据格式混乱

用户注册数据:

name phone created_at
John 138-0000-1111 2026/07/03
Jane 13800002222 03-07-2026

电话号码格式不统一,日期格式混乱。

(2) 函数的解法

SQL
-- 统一电话格式
SELECT name, REPLACE(phone, '-', '') AS clean_phone FROM users;

-- 统一日期格式
SELECT name, STR_TO_DATE(created_at, '%Y/%m/%d') AS clean_date FROM users;

3. 数学函数

函数 说明 示例
ROUND(x, d) 四舍五入 ROUND(3.1415, 2) → 3.14
CEIL(x) 向上取整 CEIL(3.1) → 4
FLOOR(x) 向下取整 FLOOR(3.9) → 3
ABS(x) 绝对值 ABS(-5) → 5
MOD(a, b) 取余 MOD(10, 3) → 1
POWER(x, y) 幂运算 POWER(2, 3) → 8
SQRT(x) 平方根 SQRT(16) → 4
RAND() 随机数 0~1 RAND() → 0.723...

▶ 示例:数学函数应用

SQL
-- 计算折扣价并四舍五入
SELECT 
    product_name,
    price,
    ROUND(price * 0.85, 2) AS sale_price
FROM products;

-- 计算页数(向上取整)
SELECT CEIL(103 / 10) AS total_pages;  -- 11 页

-- 随机排序
SELECT * FROM users ORDER BY RAND() LIMIT 5;
▶ 试一试

4. 字符串函数

函数 说明 示例
CONCAT(s1, s2, ...) 拼接字符串 CONCAT('Hello', ' ', 'World')
CONCAT_WS(sep, s1, ...) 用分隔符拼接 CONCAT_WS('-', '2026', '07', '03')
LENGTH(s) 字节长度 LENGTH('Hello') → 5
CHAR_LENGTH(s) 字符长度 CHAR_LENGTH('你好') → 2
UPPER(s) 转大写 UPPER('hello') → HELLO
LOWER(s) 转小写 LOWER('HELLO') → hello
TRIM(s) 去除首尾空格 TRIM(' hi ') → hi
LTRIM(s) 去除左侧空格 LTRIM(' hi') → hi
RTRIM(s) 去除右侧空格 RTRIM('hi ') → hi
SUBSTRING(s, pos, len) 截取子串 SUBSTRING('Hello', 2, 3) → ell
LEFT(s, n) 左侧 n 个字符 LEFT('Hello', 3) → Hel
RIGHT(s, n) 右侧 n 个字符 RIGHT('Hello', 3) → llo
REPLACE(s, old, new) 替换 REPLACE('Hi World', 'Hi', 'Hello')
REVERSE(s) 反转 REVERSE('Hello') → olleH
LPAD(s, len, pad) 左填充 LPAD('5', 3, '0') → 005
RPAD(s, len, pad) 右填充 RPAD('Hi', 5, '.') → Hi...

▶ 示例:字符串函数应用

SQL
-- 拼接全名
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees;

-- 清理电话号码
SELECT REPLACE(REPLACE(phone, '-', ''), ' ', '') AS clean_phone FROM users;

-- 截取邮箱域名
SELECT 
    email,
    SUBSTRING(email, LOCATE('@', email) + 1) AS domain
FROM users;

-- 生成订单号
SELECT CONCAT('ORD', LPAD(id, 6, '0')) AS order_no FROM orders;
▶ 试一试

输出:

TEXT 📖 仅展示
+-------------+------------+
| email       | domain     |
+-------------+------------+
| a@gmail.com | gmail.com  |
| b@163.com   | 163.com    |
+-------------+------------+

5. 日期函数

函数 说明 示例
NOW() 当前日期时间 2026-07-03 10:30:00
CURDATE() 当前日期 2026-07-03
CURTIME() 当前时间 10:30:00
DATE(dt) 提取日期部分 DATE('2026-07-03 10:30:00')
YEAR(dt) 提取年份 YEAR('2026-07-03') → 2026
MONTH(dt) 提取月份 MONTH('2026-07-03') → 7
DAY(dt) 提取日 DAY('2026-07-03') → 3
HOUR(dt) 提取小时 HOUR('10:30:00') → 10
DATE_FORMAT(dt, fmt) 格式化日期 DATE_FORMAT(NOW(), '%Y年%m月%d日')
STR_TO_DATE(s, fmt) 字符串转日期 STR_TO_DATE('2026-07-03', '%Y-%m-%d')
DATEDIFF(d1, d2) 日期差(天) DATEDIFF('2026-07-10', '2026-07-03') → 7
DATE_ADD(dt, INTERVAL) 日期加 DATE_ADD(NOW(), INTERVAL 7 DAY)
DATE_SUB(dt, INTERVAL) 日期减 DATE_SUB(NOW(), INTERVAL 1 MONTH)
TIMESTAMPDIFF(unit, d1, d2) 时间差 TIMESTAMPDIFF(YEAR, birth, CURDATE())

▶ 示例:日期函数应用

SQL
-- 查询今天的数据
SELECT * FROM orders WHERE DATE(created_at) = CURDATE();

-- 查询最近 7 天
SELECT * FROM orders WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY);

-- 按月统计
SELECT 
    DATE_FORMAT(order_date, '%Y-%m') AS month,
    COUNT(*) AS order_count,
    SUM(amount) AS total_amount
FROM orders
GROUP BY month
ORDER BY month;

-- 计算年龄
SELECT 
    name,
    birth_date,
    TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) AS age
FROM users;
▶ 试一试

输出:

TEXT 📖 仅展示
+---------+-------------+--------------+
| month   | order_count | total_amount |
+---------+-------------+--------------+
| 2026-01 |         120 |     45000.00 |
| 2026-02 |         135 |     52000.00 |
| 2026-03 |         148 |     58000.00 |
+---------+-------------+--------------+

▶ 示例:日期格式化

SQL
-- 常用格式
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d');           -- 2026-07-03
SELECT DATE_FORMAT(NOW(), '%Y年%m月%d日');       -- 2026年07月03日
SELECT DATE_FORMAT(NOW(), '%H:%i:%s');           -- 10:30:00
SELECT DATE_FORMAT(NOW(), '%W, %M %d, %Y');     -- Friday, July 03, 2026
▶ 试一试

6. 条件函数

函数 说明 示例
IF(expr, t, f) 条件判断 IF(score >= 60, 'Pass', 'Fail')
IFNULL(expr, alt) NULL 替换 IFNULL(email, 'N/A')
NULLIF(a, b) 相等返回 NULL NULLIF(1, 1) → NULL
CASE WHEN ... THEN ... END 多条件判断 见示例

▶ 示例:条件函数

SQL
-- IF 判断
SELECT 
    name,
    score,
    IF(score >= 60, 'Pass', 'Fail') AS result
FROM students;

-- IFNULL 处理 NULL
SELECT 
    name,
    IFNULL(phone, 'No phone') AS phone
FROM users;

-- CASE 多条件
SELECT 
    name,
    score,
    CASE 
        WHEN score >= 90 THEN 'A'
        WHEN score >= 80 THEN 'B'
        WHEN score >= 70 THEN 'C'
        WHEN score >= 60 THEN 'D'
        ELSE 'F'
    END AS grade
FROM students;
▶ 试一试

输出:

TEXT 📖 仅展示
+-------+-------+-------+
| name  | score | grade |
+-------+-------+-------+
| Alice |    95 | A     |
| Bob   |    82 | B     |
| Carol |    67 | D     |
| Dave  |    45 | F     |
+-------+-------+-------+

7. 聚合函数预览

函数 说明 示例
COUNT(*) 计数 SELECT COUNT(*) FROM users
SUM(col) 求和 SELECT SUM(amount) FROM orders
AVG(col) 平均值 SELECT AVG(salary) FROM employees
MAX(col) 最大值 SELECT MAX(price) FROM products
MIN(col) 最小值 SELECT MIN(age) FROM users

详见第 12 课 聚合与分组。


❓ 常见问题

Q CONCAT 中有 NULL 结果是什么?
A 结果为 NULL。用 CONCAT_WSIFNULL 处理:CONCAT_WS(' ', 'Hello', NULL) → 'Hello'。
Q NOW() 和 CURDATE() 区别?
A NOW() 返回日期+时间,CURDATE() 只返回日期。
Q 日期格式化符号在哪查?
A 搜索 "MySQL DATE_FORMAT specifiers",常用:%Y(年) %m(月) %d(日) %H(时) %i(分) %s(秒)。
Q 函数能用在 WHERE 中吗?
A 可以,但会影响索引。WHERE DATE(created_at) = CURDATE() 无法走索引,改用范围:WHERE created_at >= CURDATE() AND created_at < CURDATE() + 1

📖 小节


📝 作业

  1. 基础题(难度⭐):用 CONCAT 和 LPAD 生成订单号 'ORD000001' 格式。

  2. 进阶题(难度⭐⭐):查询最近 30 天每天的订单数量,用 DATE_FORMAT 格式化日期。

  3. 挑战题(难度⭐⭐⭐):计算每个用户的年龄,并用 CASE WHEN 分为 '少年/青年/中年/老年' 四个等级。

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏