1. 日期函数
1.1 常用日期函数概览
| 函数名称 | 描述 |
|---|---|
current_date() |
返回当前日期 |
current_time() |
返回当前时间 |
current_timestamp() |
返回当前时间戳 |
date(datetime) |
返回datetime参数的日期部分 |
date_add(date, interval d_value_type) |
在date中添加日期或时间 |
date_sub(date, interval d_value_type) |
在date中减去日期或时间 |
datediff(date1, date2) |
计算两个日期的差值(单位:天) |
now() |
返回当前日期时间 |
**interval后的数值单位可以是:** year、month、day、hour、minute、second
1.2 日期函数示例
获取当前日期时间
-- 获得年月日
SELECT current_date();
-- 结果:2017-11-19
-- 获得时分秒
SELECT current_time();
-- 结果:13:51:21
-- 获得时间戳
SELECT current_timestamp();
-- 结果:2017-11-19 13:51:48
-- 获得当前日期时间
SELECT now();
-- 结果:2017-11-19 13:51:48
日期计算
-- 在日期的基础上加日期
SELECT date_add('2017-10-28', interval 10 day);
-- 结果:2017-11-07
-- 在日期的基础上减去时间
SELECT date_sub('2017-10-1', interval 2 day);
-- 结果:2017-09-29
-- 计算两个日期之间相差多少天
SELECT datediff('2017-10-10', '2016-9-1');
-- 结果:404
1.3 实际应用案例
案例1:生日记录表
-- 创建一张表,记录生日
CREATE TABLE tmp (
id INT PRIMARY KEY AUTO_INCREMENT,
birthday DATE
);
-- 添加当前日期
INSERT INTO tmp(birthday) VALUES(current_date());
-- 查询结果
SELECT * FROM tmp;
-- 结果:
-- +----+------------+
-- | id | birthday |
-- +----+------------+
-- | 1 | 2017-11-19 |
-- +----+------------+
案例2:留言表时间处理
-- 创建留言表
CREATE TABLE msg (
id INT PRIMARY KEY AUTO_INCREMENT,
content VARCHAR(30) NOT NULL,
sendtime DATETIME
);
-- 插入数据
INSERT INTO msg(content, sendtime) VALUES('hello1', now());
INSERT INTO msg(content, sendtime) VALUES('hello2', now());
-- 显示所有留言信息,只显示日期不显示时间
SELECT content, date(sendtime) FROM msg;
-- 结果:
-- +---------+---------------+
-- | content | date(sendtime)|
-- +---------+---------------+
-- | hello1 | 2017-11-19 |
-- | hello2 | 2017-11-19 |
-- +---------+---------------+
-- 查询在2分钟内发布的帖子
SELECT * FROM msg WHERE date_add(sendtime, interval 2 minute) > now();
时间范围理解:
初始时间 now() ← 当前时间点
↓
初始时间 + 2min ← 发布时间加上2分钟
↓
发布时间在2分钟内:sendtime > now() - 2分钟
2. 字符串函数
2.1 常用字符串函数概览
| 函数名称 | 描述 |
|---|---|
charset(str) |
返回字符串字符集 |
concat(string2[, ...]) |
连接字符串 |
instr(string, substring) |
返回substring在string中出现的位置,没有返回0 |
ucase(string2) |
转换成大写 |
lcase(string2) |
转换成小写 |
left(string2, length) |
从string2中的左边起取length个字符 |
length(string) |
返回字符串长度 |
replace(str, search_str, replace_str) |
在str中用replace_str替换search_str |
strcmp(string1, string2) |
逐字符比较两字符串大小 |
substring(str, position[, length]) |
从str的position开始,取length个字符 |
ltrim(string) |
去除前导空格 |
rtrim(string) |
去除尾部空格 |
trim(string) |
去除前后空格 |
2.2 字符串函数示例
基本字符串操作
-- 获取字符集
SELECT charset(ename) FROM EMP;
-- 连接字符串(格式化显示成绩)
SELECT concat(name, '的语文是', chinese, '分, 数学是', math, '分') AS '分数'
FROM student;
-- 求字符串长度(字节数)
SELECT length(name), name FROM student;
注意: length()函数返回字符串的字节长度:
-
字母、数字:1个字节
-
中文:多个字节(与字符集编码有关)
字符串替换和截取
-- 将EMP表中所有名字中有S的替换成'上海'
SELECT replace(ename, 'S', '上海'), ename FROM EMP;
-- 截取EMP表中ename字段的第二个到第三个字符
SELECT substring(ename, 2, 2), ename FROM EMP;
-- 以首字母小写的方式显示所有员工的姓名
SELECT concat(lcase(substring(ename, 1, 1)), substring(ename, 2)) FROM EMP;
3. 数学函数
3.1 常用数学函数概览
| 函数名称 | 描述 |
|---|---|
abs(number) |
绝对值函数 |
bin(decimal_number) |
十进制转换二进制 |
hex(decimalNumber) |
转换成十六进制 |
conv(number, from_base, to_base) |
进制转换 |
ceiling(number) |
向上取整 |
floor(number) |
向下取整 |
format(number, decimal_places) |
格式化,保留小数位数 |
rand() |
返回随机浮点数,范围[0.0, 1.0) |
mod(number, denominator) |
取模,求余 |
3.2 数学函数示例
-- 绝对值
SELECT abs(-100.2); -- 结果:100.2
-- 向上取整
SELECT ceiling(23.04); -- 结果:24
-- 向下取整
SELECT floor(23.7); -- 结果:23
-- 保留2位小数位数(四舍五入)
SELECT format(12.3456, 2); -- 结果:12.35
-- 产生随机数
SELECT rand(); -- 结果:0.123456789(随机值)
-- 取模运算
SELECT mod(10, 3); -- 结果:1
4. 其他常用函数
4.1 系统信息函数
-- 查询当前用户
SELECT user();
-- 显示当前正在使用的数据库
SELECT database();
-- MySQL数据库使用该函数对用户加密
SELECT password('root');
4.2 加密函数
-- 对字符串进行md5摘要(32位字符串)
SELECT md5('admin');
-- 结果:21232f297a57a5a743894a0e4a801fc3
4.3 条件判断函数
-- ifnull(val1, val2):如果val1为null,返回val2,否则返回val1
SELECT ifnull('abc', '123'); -- 结果:abc
SELECT ifnull(null, '123'); -- 结果:123
5. 综合应用技巧
5.1 日期函数在业务中的应用
-- 查询最近7天的数据
SELECT * FROM orders WHERE order_date >= date_sub(now(), interval 7 day);
-- 计算会员注册天数
SELECT username, datediff(now(), register_date) AS '注册天数' FROM users;
-- 生日提醒(未来30天内过生日的用户)
SELECT * FROM users
WHERE month(birthday) = month(now())
AND day(birthday) BETWEEN day(now()) AND day(date_add(now(), interval 30 day));
5.2 字符串函数数据处理
-- 统一用户名格式(首字母大写,其余小写)
SELECT concat(ucase(left(username, 1)), lcase(substring(username, 2)))
FROM users;
-- 邮箱域名统计
SELECT substring_index(email, '@', -1) AS domain, count(*)
FROM users
GROUP BY domain;
-- 手机号脱敏处理
SELECT concat(left(phone, 3), '****', right(phone, 4)) AS masked_phone
FROM users;
5.3 数学函数在统计分析中的应用
-- 计算百分比(保留2位小数)
SELECT format((count1 / total) * 100, 2) AS percentage
FROM statistics;
-- 生成随机排序
SELECT * FROM products ORDER BY rand() LIMIT 10;
-- 分页计算(每页显示10条)
SELECT * FROM articles
ORDER BY create_time DESC
LIMIT 10 OFFSET 20; -- 第3页
6. 实战OJ题目类型
6.1 常见考察方向
-
日期处理:时间计算、日期格式化、时间段查询
-
字符串操作:拼接、替换、截取、格式化显示
-
数据转换:类型转换、进制转换、编码处理
-
条件判断:空值处理、条件表达式
6.2 解题技巧
-
熟练掌握函数语法:特别是参数顺序和返回值类型
-
注意字符集影响:中文字符串处理要特别注意长度计算
-
性能考虑:在大量数据时避免在WHERE条件中使用函数
-
兼容性注意:不同数据库系统的函数可能有差异
7. 使用注意事项
7.1 性能优化
-- 不推荐:在WHERE条件中使用函数(无法使用索引)
SELECT * FROM users WHERE year(create_time) = 2023;
-- 推荐:使用范围查询
SELECT * FROM users
WHERE create_time >= '2023-01-01' AND create_time < '2024-01-01';
7.2 错误处理
-- 处理可能的空值
SELECT ifnull(name, '未知用户'), ifnull(age, 0) FROM users;
-- 安全的字符串截取
SELECT substring(name, 1, 10) FROM users; -- 避免越界