【MySQL篇】内置函数:数据处理的利器

文章目录

    • 内置函数:数据处理的利器
    • 一、前言
    • 二、日期函数
      • [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 日期函数实战案例)
    • 三、字符串函数
      • [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)

规则

  1. decimal_places 指定的小数位进行 四舍五入
  2. 整数部分 每三位添加一个千分位逗号(,)
  3. 返回结果是 字符串类型(不是数值)

示例

sql 复制代码
SELECT FORMAT(1234567.891, 2);

输出

bash 复制代码
1,234,567.89

4.4 随机数

RAND() - 生成随机数

语法

sql 复制代码
RAND()
RAND(seed)

规则

  1. 返回一个 0 ≤ x < 1 的随机小数
  2. 不带参数:每次执行结果不同
  3. 带参数(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. 显示学生名字(首字母大写,其余小写)
  2. 显示三科成绩(保留 1 位小数)
  3. 显示总分(保留 0 位小数)
  4. 显示成绩等级(A/B/C/D/F)
  5. 按总分降序排列

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 中完成。
  • 保证数据一致性:统一的处理逻辑。

核心要点

  1. 日期函数:处理时间相关的数据。
  2. 字符串函数:处理文本数据。
  3. 数学函数:处理数值计算。
  4. 条件函数:实现逻辑判断。
  5. NULL 处理:避免 NULL 导致的问题。

下一篇,我们将学习复杂查询:子查询、联合查询、多表关联等。这些技术能处理更复杂的业务需求。

相关推荐
m0_678485452 分钟前
CSS如何控制表格单元格边框合并_通过border-collapse实现
jvm·数据库·python
m0_748839495 分钟前
如何用组合继承模式实现父类方法复用与子类属性独立
jvm·数据库·python
qq_3345635514 分钟前
PHP源码是否依赖特定芯片组_Intel与AMD平台差异【操作】
jvm·数据库·python
qq_206901391 小时前
如何使用C#调用Oracle存储过程_OracleCommand配置CommandType.StoredProcedure
jvm·数据库·python
m0_748839491 小时前
CSS如何实现元素平滑滚动_使用scroll-behavior属性设置
jvm·数据库·python
ShineWinsu2 小时前
对于Linux:Ext系列文件系统的解析—下
linux·面试·笔试·文件系统··ext2·挂载分区
星晨雪海2 小时前
Lombok 注解使用场景终极总结
java·数据库·mysql
风子杨yxf7712 小时前
linux下oracle开机自启动以及关机自关闭数据库,并发送邮件通知
linux·运维·数据库·oracle·自启动·发邮件·自关闭
战族狼魂3 小时前
基于LibreOffice +python 实现一个小型销售管理系统的数据库原型教学实验
数据库·python
m0_640309303 小时前
PHP函数怎样适配高可靠性存储硬件_PHP在ZFS RAIDZ环境配置【技巧】
jvm·数据库·python