文章目录
-
- 内置函数:数据处理的利器
- 一、前言
- 二、日期函数
-
- [2.1 获取当前日期和时间](#2.1 获取当前日期和时间)
-
- [CURRENT_DATE() - 获取当前日期](#CURRENT_DATE() - 获取当前日期)
- [CURRENT_TIME() - 获取当前时间](#CURRENT_TIME() - 获取当前时间)
- [CURRENT_TIMESTAMP() - 获取当前日期时间](#CURRENT_TIMESTAMP() - 获取当前日期时间)
- [NOW() - 同 CURRENT_TIMESTAMP()](#NOW() - 同 CURRENT_TIMESTAMP())
- [2.2 日期计算](#2.2 日期计算)
-
- [DATE_ADD() - 日期加法](#DATE_ADD() - 日期加法)
- [DATE_SUB() - 日期减法](#DATE_SUB() - 日期减法)
- [2.3 日期差值计算](#2.3 日期差值计算)
-
- [DATEDIFF() - 计算两个日期相差的天数](#DATEDIFF() - 计算两个日期相差的天数)
- [2.4 提取日期部分](#2.4 提取日期部分)
-
- [DATE() - 从日期时间中提取日期](#DATE() - 从日期时间中提取日期)
- [TIME() - 从日期时间中提取时间](#TIME() - 从日期时间中提取时间)
- [YEAR()、MONTH()、DAY() - 提取年月日](#YEAR()、MONTH()、DAY() - 提取年月日)
- [2.5 日期函数实战案例](#2.5 日期函数实战案例)
-
- 案例一:记录生日并计算年龄
- [案例二:查询最近 2 分钟内发布的留言](#案例二:查询最近 2 分钟内发布的留言)
- 三、字符串函数
-
- [3.1 字符串长度](#3.1 字符串长度)
-
- [LENGTH() - 获取字符串长度(字节数)](#LENGTH() - 获取字符串长度(字节数))
- [CHAR_LENGTH() - 获取字符数](#CHAR_LENGTH() - 获取字符数)
- [3.2 字符串拼接](#3.2 字符串拼接)
-
- [CONCAT() - 拼接字符串](#CONCAT() - 拼接字符串)
- [3.3 字符串替换](#3.3 字符串替换)
-
- [REPLACE() - 替换字符串](#REPLACE() - 替换字符串)
- [3.4 字符串截取](#3.4 字符串截取)
-
- [SUBSTRING() - 截取字符串](#SUBSTRING() - 截取字符串)
- [3.5 大小写转换](#3.5 大小写转换)
-
- [UPPER() - 转换为大写](#UPPER() - 转换为大写)
- [LOWER() - 转换为小写](#LOWER() - 转换为小写)
- [LCASE() - 同 LOWER()](#LCASE() - 同 LOWER())
- [3.6 字符串去空格](#3.6 字符串去空格)
-
- [TRIM() - 去除前后空格](#TRIM() - 去除前后空格)
- [LTRIM() - 去除左边空格](#LTRIM() - 去除左边空格)
- [RTRIM() - 去除右边空格](#RTRIM() - 去除右边空格)
- 四、数学函数
-
- [4.1 绝对值](#4.1 绝对值)
-
- [ABS() - 绝对值](#ABS() - 绝对值)
- [4.2 取整函数](#4.2 取整函数)
-
- [CEILING() - 向上取整](#CEILING() - 向上取整)
- [FLOOR() - 向下取整](#FLOOR() - 向下取整)
- [ROUND() - 四舍五入](#ROUND() - 四舍五入)
- [4.3 格式化数字](#4.3 格式化数字)
-
- [FORMAT() - 格式化数字](#FORMAT() - 格式化数字)
- [4.4 随机数](#4.4 随机数)
-
- [RAND() - 生成随机数](#RAND() - 生成随机数)
- 五、其他常用函数
-
- [5.1 用户和数据库信息](#5.1 用户和数据库信息)
-
- [USER() - 获取当前用户](#USER() - 获取当前用户)
- [DATABASE() - 获取当前数据库](#DATABASE() - 获取当前数据库)
- [5.2 加密函数](#5.2 加密函数)
-
- [MD5() - MD5 加密](#MD5() - MD5 加密)
- [PASSWORD() - MySQL 密码加密](#PASSWORD() - MySQL 密码加密)
- [5.3 NULL 处理](#5.3 NULL 处理)
-
- [IFNULL() - NULL 值处理](#IFNULL() - NULL 值处理)
- [COALESCE() - 返回第一个非 NULL 值](#COALESCE() - 返回第一个非 NULL 值)
- [5.4 条件函数](#5.4 条件函数)
-
- [IF() - 条件判断](#IF() - 条件判断)
- [CASE WHEN - 多条件判断](#CASE WHEN - 多条件判断)
- 六、函数组合应用
-
- [6.1 复杂查询示例](#6.1 复杂查询示例)
- [6.2 数据清洗示例](#6.2 数据清洗示例)
- 七、常用函数速查表
-
- [7.1 日期函数速查](#7.1 日期函数速查)
- [7.2 字符串函数速查](#7.2 字符串函数速查)
- [7.3 数学函数速查](#7.3 数学函数速查)
- [7.4 其他函数速查](#7.4 其他函数速查)
- 八、总结与最佳实践
-
- [8.1 函数使用建议](#8.1 函数使用建议)
- [8.2 常见错误](#8.2 常见错误)
- [8.3 性能考虑](#8.3 性能考虑)
- 九、实战练习
-
- [9.1 综合查询练习](#9.1 综合查询练习)
- [9.2 数据清洗练习](#9.2 数据清洗练习)
- 十、总结
内置函数:数据处理的利器
一、前言
💬 这一篇讲什么:MySQL 的内置函数
🚀 核心内容:
- 如何处理日期和时间?
- 如何处理字符串?
- 如何进行数学运算?
- 还有哪些实用函数?
在前一篇中,我们学会了基本的 CRUD 操作和聚合函数。现在需要学习 MySQL 提供的各种内置函数,这些函数能大大简化数据处理的复杂度。MySQL 提供了数百个内置函数,这一篇讲解最常用的几类。
二、日期函数
2.1 获取当前日期和时间
CURRENT_DATE() - 获取当前日期
sql
SELECT CURRENT_DATE();
输出示例:
bash
+----------------+
| CURRENT_DATE() |
+----------------+
| 2024-04-07 |
+----------------+
CURRENT_TIME() - 获取当前时间
sql
SELECT CURRENT_TIME();
输出示例:
bash
+----------------+
| CURRENT_TIME() |
+----------------+
| 14:35:22 |
+----------------+
CURRENT_TIMESTAMP() - 获取当前日期时间
sql
SELECT CURRENT_TIMESTAMP();
输出示例:
bash
+---------------------+
| CURRENT_TIMESTAMP() |
+---------------------+
| 2024-04-07 14:35:48 |
+---------------------+
NOW() - 同 CURRENT_TIMESTAMP()
sql
SELECT NOW();
输出与 CURRENT_TIMESTAMP() 相同。
2.2 日期计算
DATE_ADD() - 日期加法
语法:
sql
DATE_ADD(date, INTERVAL value unit)
示例:
sql
-- 在 2024-04-07 的基础上加 10 天
SELECT DATE_ADD('2024-04-07', INTERVAL 10 DAY);
输出:
bash
+----------------------------------------+
| DATE_ADD('2024-04-07', INTERVAL 10 DAY)|
+----------------------------------------+
| 2024-04-17 |
+----------------------------------------+
支持的时间单位:
| 单位 | 说明 | 例子 |
|---|---|---|
DAY |
天 | INTERVAL 10 DAY |
MONTH |
月 | INTERVAL 3 MONTH |
YEAR |
年 | INTERVAL 1 YEAR |
HOUR |
小时 | INTERVAL 2 HOUR |
MINUTE |
分钟 | INTERVAL 30 MINUTE |
SECOND |
秒 | INTERVAL 45 SECOND |
更多示例:
sql
-- 加 3 个月
SELECT DATE_ADD('2024-04-07', INTERVAL 3 MONTH);
-- 加 1 年
SELECT DATE_ADD('2024-04-07', INTERVAL 1 YEAR);
-- 加 2 小时
SELECT DATE_ADD('2024-04-07 14:00:00', INTERVAL 2 HOUR);
DATE_SUB() - 日期减法
语法:
sql
DATE_SUB(date, INTERVAL value unit)
示例:
sql
-- 在 2024-04-07 的基础上减 2 天
SELECT DATE_SUB('2024-04-07', INTERVAL 2 DAY);
输出:
bash
+----------------------------------------+
| DATE_SUB('2024-04-07', INTERVAL 2 DAY) |
+----------------------------------------+
| 2024-04-05 |
+----------------------------------------+
2.3 日期差值计算
DATEDIFF() - 计算两个日期相差的天数
语法:
sql
DATEDIFF(date1, date2)
返回 date1 - date2 的天数。
示例:
sql
-- 计算 2024-04-07 和 2023-04-07 相差多少天
SELECT DATEDIFF('2024-04-07', '2023-04-07');
输出:
bash
+--------------------------------------+
| DATEDIFF('2024-04-07', '2023-04-07') |
+--------------------------------------+
| 366 |
+--------------------------------------+
(2024 年是闰年,所以相差 366 天)
2.4 提取日期部分
DATE() - 从日期时间中提取日期
sql
SELECT DATE('2024-04-07 14:35:22');
输出:
bash
+----------------------------+
| DATE('2024-04-07 14:35:22')|
+----------------------------+
| 2024-04-07 |
+----------------------------+
TIME() - 从日期时间中提取时间
sql
SELECT TIME('2024-04-07 14:35:22');
输出:
bash
+----------------------------+
| TIME('2024-04-07 14:35:22')|
+----------------------------+
| 14:35:22 |
+----------------------------+
YEAR()、MONTH()、DAY() - 提取年月日
sql
SELECT
YEAR('2024-04-07') AS 年,
MONTH('2024-04-07') AS 月,
DAY('2024-04-07') AS 日;
输出:
bash
+----+----+----+
| 年 | 月 | 日 |
+----+----+----+
| 2024| 4 | 7 |
+----+----+----+
2.5 日期函数实战案例
案例一:记录生日并计算年龄
创建表:
sql
CREATE TABLE users (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20),
birthday DATE
);
插入数据:
sql
INSERT INTO users (name, birthday) VALUES
('张三', '1990-05-15'),
('李四', '1995-08-20'),
('王五', '2000-12-10');
查询并计算年龄:
sql
SELECT
name,
birthday,
YEAR(CURRENT_DATE()) - YEAR(birthday) AS 年龄
FROM users;
输出:
bash
+------+------------+------+
| name | birthday | 年龄 |
+------+------------+------+
| 张三 | 1990-05-15 | 34 |
| 李四 | 1995-08-20 | 29 |
| 王五 | 2000-12-10 | 24 |
+------+------------+------+
案例二:查询最近 2 分钟内发布的留言
创建表:
sql
CREATE TABLE messages (
id INT PRIMARY KEY AUTO_INCREMENT,
content VARCHAR(100),
sendtime DATETIME
);
插入数据:
sql
INSERT INTO messages (content, sendtime) VALUES
('hello1', NOW()),
('hello2', NOW()),
('hello3', DATE_SUB(NOW(), INTERVAL 5 MINUTE));
查询最近 2 分钟内的留言:
sql
SELECT content, sendtime FROM messages
WHERE DATE_ADD(sendtime, INTERVAL 2 MINUTE) > NOW();
这个查询的逻辑是:如果留言时间加上 2 分钟后仍然大于当前时间,说明留言是在最近 2 分钟内发布的。
三、字符串函数
3.1 字符串长度
LENGTH() - 获取字符串长度(字节数)
重要:LENGTH() 返回的是字节数,不是字符数。
sql
SELECT LENGTH('hello');
输出:
bash
+----------------+
| LENGTH('hello') |
+----------------+
| 5 |
+----------------+
中文字符的处理:
在 UTF-8 编码下,一个中文字符占 3 个字节。
sql
SELECT LENGTH('你好');
输出:
bash
+---------------+
| LENGTH('你好') |
+---------------+
| 6 |
+---------------+
(2 个中文字符 × 3 字节 = 6 字节)
CHAR_LENGTH() - 获取字符数
如果需要字符数而不是字节数,使用 CHAR_LENGTH():
sql
SELECT CHAR_LENGTH('你好');
输出:
bash
+-------------------+
| CHAR_LENGTH('你好')|
+-------------------+
| 2 |
+-------------------+
3.2 字符串拼接
CONCAT() - 拼接字符串
语法:
sql
CONCAT(str1, str2, str3, ...)
示例:
sql
SELECT CONCAT('Hello', ' ', 'World');
输出:
+-------------------------------+
| CONCAT('Hello', ' ', 'World') |
+-------------------------------+
| Hello World |
+-------------------------------+
实战案例:格式化学生成绩信息
sql
-- 假设有 exam_result 表
SELECT CONCAT(
name,
'的语文是', chinese,
'分,数学是', math,
'分,英语是', english,
'分'
) AS 成绩信息
FROM exam_result;
输出:
bash
+------------------------------------------+
| 成绩信息 |
+------------------------------------------+
| 唐三藏的语文是134分,数学是98分,英语是56分|
| 孙悟空的语文是174分,数学是80分,英语是77分|
+------------------------------------------+
3.3 字符串替换
REPLACE() - 替换字符串
语法:
sql
REPLACE(str, from_str, to_str)
将 str 中的所有 from_str 替换为 to_str。
示例:
sql
SELECT REPLACE('Hello World', 'World', 'MySQL');
输出:
bAH
+------------------------------------------+
| REPLACE('Hello World', 'World', 'MySQL') |
+------------------------------------------+
| Hello MySQL |
+------------------------------------------+
实战案例:替换员工名字中的特定字符
sql
-- 假设有 emp 表,将名字中的 'S' 替换为 '上海'
SELECT REPLACE(ename, 'S', '上海') AS 新名字, ename AS 原名字
FROM emp;
3.4 字符串截取
SUBSTRING() - 截取字符串
语法:
sql
SUBSTRING(str, pos, len)
pos:起始位置(从 1 开始,不是 0)。len:可选,截取长度。如不指定,则截取到末尾。
示例:
sql
-- 从第 2 个字符开始,截取 3 个字符
SELECT SUBSTRING('Hello World', 2, 3);
输出:
bash
+--------------------------------+
| SUBSTRING('Hello World', 2, 3) |
+--------------------------------+
| ell |
+--------------------------------+
实战案例:截取员工名字的第 2 到第 3 个字符
sql
SELECT SUBSTRING(ename, 2, 2) AS 截取结果, ename AS 原名字
FROM emp;
3.5 大小写转换
UPPER() - 转换为大写
sql
SELECT UPPER('hello');
输出:
bash
+----------------+
| UPPER('hello') |
+----------------+
| HELLO |
+----------------+
LOWER() - 转换为小写
sql
SELECT LOWER('HELLO');
输出:
bash
+----------------+
| LOWER('HELLO') |
+----------------+
| hello |
+----------------+
LCASE() - 同 LOWER()
sql
SELECT LCASE('HELLO');
实战案例:首字母小写显示员工名字
sql
-- 将员工名字的首字母转为小写
SELECT CONCAT(
LCASE(SUBSTRING(ename, 1, 1)),
SUBSTRING(ename, 2)
) AS 首字母小写
FROM emp;
输出示例:
bash
+----------+
| 首字母小写|
+----------+
| sMITH |
| aLLEN |
+----------+
3.6 字符串去空格
TRIM() - 去除前后空格
sql
SELECT TRIM(' hello ');
输出:
bash
+------------------+
| TRIM(' hello ')|
+------------------+
| hello |
+------------------+
LTRIM() - 去除左边空格
sql
SELECT LTRIM(' hello ');
RTRIM() - 去除右边空格
sql
SELECT RTRIM(' hello ');
四、数学函数
4.1 绝对值
ABS() - 绝对值
sql
SELECT ABS(-100.5);
输出:
bash
+-------------+
| ABS(-100.5) |
+-------------+
| 100.5 |
+-------------+
4.2 取整函数
CEILING() - 向上取整
sql
SELECT CEILING(23.04);
输出:
bash
+----------------+
| CEILING(23.04) |
+----------------+
| 24 |
+----------------+
FLOOR() - 向下取整
sql
SELECT FLOOR(23.99);
输出:
bash
+-------------+
| FLOOR(23.99)|
+-------------+
| 23 |
+-------------+
ROUND() - 四舍五入
sql
SELECT ROUND(23.567, 2);
输出:
bash
+------------------+
| ROUND(23.567, 2) |
+------------------+
| 23.57 |
+------------------+
4.3 格式化数字
FORMAT() - 格式化数字
语法:
sql
FORMAT(number, decimal_places)
规则:
- 按
decimal_places指定的小数位进行 四舍五入 - 整数部分 每三位添加一个千分位逗号(,)
- 返回结果是 字符串类型(不是数值)
示例:
sql
SELECT FORMAT(1234567.891, 2);
输出:
bash
1,234,567.89
4.4 随机数
RAND() - 生成随机数
语法:
sql
RAND()
RAND(seed)
规则:
- 返回一个 0 ≤ x < 1 的随机小数
- 不带参数:每次执行结果不同
- 带参数(seed):结果固定(伪随机)
示例:
sql
SELECT RAND();
输出:
bash
0.8273490574692265
生成指定范围的随机数:
sql
-- 生成 1 到 100 之间的随机整数
SELECT FLOOR(RAND() * 100) + 1;
五、其他常用函数
5.1 用户和数据库信息
USER() - 获取当前用户
sql
SELECT USER();
输出:
bash
+----------------+
| USER() |
+----------------+
| root@localhost |
+----------------+
DATABASE() - 获取当前数据库
sql
SELECT DATABASE();
输出:
bash
+------------+
| DATABASE() |
+------------+
| mydb |
+------------+
5.2 加密函数
MD5() - MD5 加密
MD5 是一种单向加密算法,常用于密码存储。
sql
SELECT MD5('admin');
输出:
bash
+----------------------------------+
| MD5('admin') |
+----------------------------------+
| 21232f297a57a5a743894a0e4a801fc3|
+----------------------------------+
特点:
- 相同的输入总是产生相同的输出。
- 无法反向解密。
- 常用于密码验证。
PASSWORD() - MySQL 密码加密
这是 MySQL 内部使用的密码加密函数(已过时,不推荐在新应用中使用)。
sql
SELECT PASSWORD('root');
输出:
bash
+-------------------------------------------+
| PASSWORD('root') |
+-------------------------------------------+
| *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B|
+-------------------------------------------+
5.3 NULL 处理
IFNULL() - NULL 值处理
语法:
sql
IFNULL(expr1, expr2)
如果 expr1 为 NULL,返回 expr2;否则返回 expr1。
示例:
sql
SELECT IFNULL('abc', '123');
输出:
bash
+---------------------+
| IFNULL('abc', '123')|
+---------------------+
| abc |
+---------------------+
sql
SELECT IFNULL(NULL, '123');
输出:
bash
+--------------------+
| IFNULL(NULL, '123')|
+--------------------+
| 123 |
+--------------------+
实战案例:处理可能为 NULL 的字段
sql
-- 假设 students 表中 qq 字段可能为 NULL
SELECT
name,
IFNULL(qq, '未填写') AS qq号
FROM students;
输出:
bash
+------+------+
| name | qq号 |
+------+------+
| 张三 | 未填写|
| 李四 | 11111|
+------+------+
COALESCE() - 返回第一个非 NULL 值
语法:
sql
COALESCE(expr1, expr2, expr3, ...)
返回参数列表中第一个非 NULL 的值。
示例:
sql
SELECT COALESCE(NULL, NULL, 'hello', 'world');
输出:
bash
+----------------------------------------+
| COALESCE(NULL, NULL, 'hello', 'world') |
+----------------------------------------+
| hello |
+----------------------------------------+
5.4 条件函数
IF() - 条件判断
语法:
sql
IF(condition, value_if_true, value_if_false)
示例:
sql
SELECT IF(10 > 5, '是', '否');
输出:
bash
+---------------------+
| IF(10 > 5, '是', '否')|
+---------------------+
| 是 |
+---------------------+
实战案例:根据成绩判断是否及格
sql
SELECT
name,
math,
IF(math >= 60, '及格', '不及格') AS 状态
FROM exam_result;
输出:
bash
+-----------+------+------+
| name | math | 状态 |
+-----------+------+------+
| 唐三藏 | 98 | 及格 |
| 孙悟空 | 80 | 及格 |
| 猪悟能 | 98 | 及格 |
| 曹孟德 | 60 | 及格 |
| 刘玄德 | 115 | 及格 |
| 孙权 | 73 | 及格 |
| 宋公明 | 95 | 及格 |
+-----------+------+------+
CASE WHEN - 多条件判断
语法:
sql
CASE
WHEN condition1 THEN result1
WHEN condition2 THEN result2
...
ELSE result_default
END
示例:根据成绩判断等级
sql
SELECT
name,
math,
CASE
WHEN math >= 90 THEN 'A'
WHEN math >= 80 THEN 'B'
WHEN math >= 70 THEN 'C'
WHEN math >= 60 THEN 'D'
ELSE 'F'
END AS 等级
FROM exam_result;
输出:
bash
+-----------+------+------+
| name | math | 等级 |
+-----------+------+------+
| 唐三藏 | 98 | A |
| 孙悟空 | 80 | B |
| 猪悟能 | 98 | A |
| 曹孟德 | 60 | D |
| 刘玄德 | 115 | A |
| 孙权 | 73 | C |
| 宋公明 | 95 | A |
+-----------+------+------+
六、函数组合应用
6.1 复杂查询示例
需求:显示所有学生的成绩信息,格式为"学生名字的语文是 XX 分,数学是 XX 分,英语是 XX 分",并计算总分,按总分降序排列。
sql
SELECT
CONCAT(
name,
'的语文是', ROUND(chinese, 0),
'分,数学是', ROUND(math, 0),
'分,英语是', ROUND(english, 0),
'分'
) AS 成绩信息,
ROUND(chinese + math + english, 0) AS 总分
FROM exam_result
ORDER BY 总分 DESC;
6.2 数据清洗示例
需求:清理用户输入的数据,去除前后空格,转换为小写,并检查是否为空。
sql
SELECT
TRIM(LOWER(username)) AS 清理后的用户名,
IFNULL(TRIM(email), '未填写') AS 邮箱
FROM users;
七、常用函数速查表
7.1 日期函数速查
| 函数 | 说明 | 例子 |
|---|---|---|
CURRENT_DATE() |
当前日期 | 2024-04-07 |
CURRENT_TIME() |
当前时间 | 14:35:22 |
NOW() |
当前日期时间 | 2024-04-07 14:35:22 |
DATE_ADD(date, INTERVAL n UNIT) |
日期加法 | DATE_ADD(NOW(), INTERVAL 1 DAY) |
DATE_SUB(date, INTERVAL n UNIT) |
日期减法 | DATE_SUB(NOW(), INTERVAL 1 HOUR) |
DATEDIFF(date1, date2) |
日期差(天) | DATEDIFF('2024-04-07', '2024-04-01') |
DATE(datetime) |
提取日期 | DATE(NOW()) |
TIME(datetime) |
提取时间 | TIME(NOW()) |
YEAR(date) |
提取年 | YEAR(NOW()) |
MONTH(date) |
提取月 | MONTH(NOW()) |
DAY(date) |
提取日 | DAY(NOW()) |
7.2 字符串函数速查
| 函数 | 说明 | 例子 |
|---|---|---|
LENGTH(str) |
字符串长度(字节) | LENGTH('hello') = 5 |
CHAR_LENGTH(str) |
字符串长度(字符数) | CHAR_LENGTH('你好') = 2 |
CONCAT(str1, str2, ...) |
字符串拼接 | CONCAT('Hello', ' ', 'World') |
REPLACE(str, from, to) |
字符串替换 | REPLACE('hello', 'l', 'L') |
SUBSTRING(str, pos, len) |
字符串截取 | SUBSTRING('hello', 2, 3) = 'ell' |
UPPER(str) |
转大写 | UPPER('hello') = 'HELLO' |
LOWER(str) |
转小写 | LOWER('HELLO') = 'hello' |
LCASE(str) |
转小写(同 LOWER) | LCASE('HELLO') = 'hello' |
TRIM(str) |
去前后空格 | TRIM(' hello ') = 'hello' |
LTRIM(str) |
去左边空格 | LTRIM(' hello') = 'hello' |
RTRIM(str) |
去右边空格 | RTRIM('hello ') = 'hello' |
7.3 数学函数速查
| 函数 | 说明 | 例子 |
|---|---|---|
ABS(num) |
绝对值 | ABS(-100.5) = 100.5 |
CEILING(num) |
向上取整 | CEILING(23.04) = 24 |
FLOOR(num) |
向下取整 | FLOOR(23.99) = 23 |
ROUND(num, decimal) |
四舍五入 | ROUND(23.567, 2) = 23.57 |
FORMAT(num, decimal) |
格式化数字 | FORMAT(1234567.89, 2) = '1,234,567.89' |
RAND() |
随机数 | RAND() 返回 0-1 之间的随机数 |
7.4 其他函数速查
| 函数 | 说明 | 例子 |
|---|---|---|
USER() |
当前用户 | root@localhost |
DATABASE() |
当前数据库 | mydb |
MD5(str) |
MD5 加密 | MD5('admin') = '21232f297a57a5a743894a0e4a801fc3' |
PASSWORD(str) |
MySQL 密码加密 | 已过时,不推荐使用 |
IFNULL(expr1, expr2) |
NULL 处理 | IFNULL(NULL, '默认值') = '默认值' |
COALESCE(expr1, expr2, ...) |
返回第一个非 NULL | COALESCE(NULL, NULL, 'hello') = 'hello' |
IF(condition, true, false) |
条件判断 | IF(10 > 5, '是', '否') = '是' |
CASE WHEN ... THEN ... END |
多条件判断 | 见下面示例 |
八、总结与最佳实践
现在你已经掌握了:
✅ 日期函数:获取当前日期时间、日期计算、日期差值、日期部分提取
✅ 字符串函数:长度、拼接、替换、截取、大小写转换、去空格
✅ 数学函数:绝对值、取整、四舍五入、格式化、随机数
✅ 其他函数:用户信息、加密、NULL 处理、条件判断
✅ 函数组合:复杂查询、数据清洗
8.1 函数使用建议
日期函数:
- 使用
NOW()或CURRENT_TIMESTAMP()记录当前时间。 - 使用
DATE_ADD()和DATE_SUB()进行日期计算。 - 使用
DATEDIFF()计算两个日期的差值。 - 使用
DATE()、TIME()提取日期时间的部分。
字符串函数:
- 使用
CONCAT()拼接字符串,比+更安全(NULL 处理)。 - 使用
TRIM()清理用户输入的数据。 - 使用
REPLACE()进行批量替换。 - 使用
SUBSTRING()截取字符串。 - 注意
LENGTH()返回字节数,中文字符占多个字节。
数学函数:
- 使用
ROUND()而不是FORMAT()进行数学运算(FORMAT 返回字符串)。 - 使用
CEILING()和FLOOR()进行精确的取整。 - 使用
FORMAT()仅用于显示格式化的数字。
NULL 处理:
- 使用
IFNULL()处理单个 NULL 值。 - 使用
COALESCE()处理多个可能为 NULL 的值。 - 在 SELECT 中使用这些函数,避免 NULL 导致的计算错误。
条件判断:
- 简单条件用
IF()。 - 复杂多条件用
CASE WHEN。 - 在 SELECT 中使用,可以动态生成新列。
8.2 常见错误
❌ 错误一:混淆 LENGTH() 和 CHAR_LENGTH()
sql
-- 错误:期望得到 2,实际得到 6(UTF-8 中文 3 字节)
SELECT LENGTH('你好');
-- 正确:使用 CHAR_LENGTH() 获取字符数
SELECT CHAR_LENGTH('你好');
❌ 错误二:CONCAT() 中包含 NULL
sql
-- 错误:结果为 NULL
SELECT CONCAT('Hello', NULL, 'World');
-- 正确:使用 IFNULL() 处理 NULL
SELECT CONCAT('Hello', IFNULL(NULL, ''), 'World');
❌ 错误三:用 FORMAT() 进行数学运算
sql
-- 错误:FORMAT 返回字符串,不能用于计算
SELECT FORMAT(100.5, 2) + 50; -- 错误
-- 正确:用 ROUND() 进行数学运算
SELECT ROUND(100.5, 2) + 50;
❌ 错误四:日期函数的单位拼写
sql
-- 错误:单位应该是 DAY,不是 DAYS
SELECT DATE_ADD(NOW(), INTERVAL 1 DAYS);
-- 正确
SELECT DATE_ADD(NOW(), INTERVAL 1 DAY);
8.3 性能考虑
- 在 WHERE 中使用函数:可能导致索引失效,查询变慢。
- 在 SELECT 中使用函数:通常没有性能问题。
- 避免在 WHERE 中对列使用函数 :比如
WHERE YEAR(birthday) = 2000会导致全表扫描。
优化示例:
sql
-- 不推荐(无法使用索引)
SELECT * FROM users WHERE YEAR(birthday) = 2000;
-- 推荐(可以使用索引)
SELECT * FROM users WHERE birthday BETWEEN '2000-01-01' AND '2000-12-31';
九、实战练习
9.1 综合查询练习
需求:查询所有学生的成绩信息,要求:
- 显示学生名字(首字母大写,其余小写)
- 显示三科成绩(保留 1 位小数)
- 显示总分(保留 0 位小数)
- 显示成绩等级(A/B/C/D/F)
- 按总分降序排列
SQL 语句:
sql
SELECT
CONCAT(
UPPER(SUBSTRING(name, 1, 1)),
LOWER(SUBSTRING(name, 2))
) AS 学生名字,
ROUND(chinese, 1) AS 语文,
ROUND(math, 1) AS 数学,
ROUND(english, 1) AS 英语,
ROUND(chinese + math + english, 0) AS 总分,
CASE
WHEN chinese + math + english >= 270 THEN 'A'
WHEN chinese + math + english >= 240 THEN 'B'
WHEN chinese + math + english >= 210 THEN 'C'
WHEN chinese + math + english >= 180 THEN 'D'
ELSE 'F'
END AS 等级
FROM exam_result
ORDER BY chinese + math + english DESC;
9.2 数据清洗练习
需求:清理用户表中的数据
sql
SELECT
id,
TRIM(LOWER(username)) AS 用户名,
IFNULL(TRIM(email), '未填写') AS 邮箱,
IFNULL(TRIM(phone), '未填写') AS 电话,
DATE_FORMAT(created_at, '%Y-%m-%d') AS 创建日期,
DATEDIFF(CURRENT_DATE(), DATE(created_at)) AS 注册天数
FROM users
WHERE created_at IS NOT NULL
ORDER BY created_at DESC;
十、总结
MySQL 的内置函数极大地简化了数据处理的复杂度。通过合理使用这些函数,可以:
- 提高查询效率:在数据库层面处理数据,减少应用层的处理。
- 简化代码:复杂的数据转换在 SQL 中完成。
- 保证数据一致性:统一的处理逻辑。
核心要点:
- 日期函数:处理时间相关的数据。
- 字符串函数:处理文本数据。
- 数学函数:处理数值计算。
- 条件函数:实现逻辑判断。
- NULL 处理:避免 NULL 导致的问题。
下一篇,我们将学习复杂查询:子查询、联合查询、多表关联等。这些技术能处理更复杂的业务需求。