1. MySQL函数体系概览
MySQL作为最流行的关系型数据库之一,其内置函数体系是数据处理的核心武器库。这些函数主要分为四大类:日期时间函数、字符串函数、数学函数以及系统信息函数。实际开发中,合理运用这些函数能显著减少应用层代码量,提升查询效率。根据我的项目经验,在千万级数据表上,一个恰当的日期函数使用可能将查询时间从秒级降到毫秒级。
2. 日期时间函数深度解析
2.1 基础日期操作
sql复制-- 获取当前日期时间
SELECT NOW(); -- 2023-07-20 14:30:45
SELECT CURDATE(); -- 2023-07-20
SELECT CURTIME(); -- 14:30:45
-- 日期加减运算(重要业务场景)
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY); -- 7天后
SELECT DATE_SUB('2023-12-31', INTERVAL 3 MONTH); -- 2023-09-30
特别注意:DATE_ADD/DATE_SUB的INTERVAL参数支持MICROSECOND到YEAR的15种时间单位,在账单周期计算中特别实用。
2.2 日期格式化与解析
sql复制-- 日期格式化(报表常用)
SELECT DATE_FORMAT(NOW(), '%Y年%m月%d日 %H时%i分'); -- 2023年07月20日 14时30分
-- 字符串转日期(数据清洗必备)
SELECT STR_TO_DATE('July 20 2023', '%M %d %Y'); -- 2023-07-20
日期格式符对照表:
| 格式符 | 含义 | 示例 |
|---|---|---|
| %Y | 四位年份 | 2023 |
| %y | 两位年份 | 23 |
| %m | 数字月份(01-12) | 07 |
| %M | 英文月份 | July |
| %d | 月份中的天数 | 20 |
| %H | 24小时制小时 | 14 |
2.3 日期差异计算
sql复制-- 计算天数差(电商场景常用)
SELECT DATEDIFF('2023-07-25', '2023-07-20'); -- 5
-- 精确时间差(适合计时场景)
SELECT TIMESTAMPDIFF(MINUTE, '2023-07-20 14:00', '2023-07-20 14:30'); -- 30
3. 字符串函数实战技巧
3.1 基础字符串处理
sql复制-- 连接字符串(避免应用层拼接)
SELECT CONCAT(last_name, ', ', first_name) AS full_name FROM employees;
-- 带分隔符连接(批量生成CSV)
SELECT CONCAT_WS('|', id, name, age) FROM users;
3.2 字符串截取与定位
sql复制-- 提取子串(处理固定格式数据)
SELECT SUBSTRING('MySQL-Function', 7, 8); -- Function
-- 智能定位(日志分析场景)
SELECT
SUBSTRING(log_content, 1, LOCATE('ERROR', log_content)-1) AS pre_error,
SUBSTRING(log_content, LOCATE('ERROR', log_content)) AS error_part
FROM system_logs;
3.3 字符串替换与格式化
sql复制-- 掩码处理(数据脱敏)
SELECT INSERT(phone, 4, 4, '****') FROM customers;
-- 大小写转换(统一检索条件)
SELECT LOWER(user_input) = LOWER(db_value);
4. 数学函数精准运用
4.1 基础计算函数
sql复制-- 精度控制(财务系统关键)
SELECT ROUND(123.4567, 2); -- 123.46
SELECT TRUNCATE(123.4567, 2); -- 123.45
-- 随机抽样(数据分析场景)
SELECT * FROM products ORDER BY RAND() LIMIT 10;
4.2 高级数学运算
sql复制-- 对数运算(科学计算)
SELECT LOG(2, 8); -- 3
-- 三角函数(地理计算)
SELECT SIN(RADIANS(30)); -- 0.5
5. 其他实用函数锦囊
5.1 流程控制函数
sql复制-- 条件判断(替代简单CASE WHEN)
SELECT IF(score >= 60, '及格', '不及格') FROM exams;
-- 复杂条件判断
SELECT
name,
CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
ELSE 'C'
END AS grade
FROM students;
5.2 系统信息函数
sql复制-- 连接信息监控
SELECT CONNECTION_ID(); -- 当前连接ID
SELECT USER(); -- 当前用户
SELECT DATABASE(); -- 当前数据库
5.3 加密函数
sql复制-- 基础加密(密码存储)
SELECT MD5('password123');
SELECT SHA2('password123', 256);
-- 高级加密(需SSL支持)
SELECT AES_ENCRYPT('secret', 'key');
6. 函数性能优化实践
6.1 索引与函数陷阱
sql复制-- 错误示例(导致索引失效)
SELECT * FROM orders WHERE DATE_FORMAT(create_time,'%Y-%m') = '2023-07';
-- 正确写法(保持索引有效性)
SELECT * FROM orders
WHERE create_time BETWEEN '2023-07-01' AND '2023-07-31';
6.2 批量处理优化
sql复制-- 低效写法(逐行处理)
UPDATE products SET price = ROUND(price * 1.1, 2);
-- 高效写法(单次计算)
UPDATE products SET price =
(SELECT ROUND(avg_price * 1.1, 2) FROM (SELECT AVG(price) AS avg_price FROM products) t);
7. 函数组合应用案例
7.1 数据清洗模板
sql复制-- 清理混合格式电话号码
UPDATE contacts SET phone =
CONCAT_WS('-',
SUBSTRING(REPLACE(phone, ' ', ''), 1, 3),
SUBSTRING(REPLACE(phone, ' ', ''), 4, 4),
SUBSTRING(REPLACE(phone, ' ', ''), 8)
)
WHERE phone REGEXP '[^0-9]';
7.2 动态SQL生成
sql复制-- 生成月度报表查询语句
SET @sql = CONCAT(
'SELECT department, ',
GROUP_CONCAT(
CONCAT('SUM(CASE WHEN MONTH(create_time) = ',
month, ' THEN amount END) AS m', month)
SEPARATOR ', '
),
' FROM sales GROUP BY department'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
8. 版本差异与兼容方案
MySQL各版本函数差异对照表:
| 函数特性 | 5.7版本 | 8.0版本改进 |
|---|---|---|
| 窗口函数 | 不支持 | 支持RANK(), OVER()等 |
| JSON处理 | 基础支持 | 新增JSON_TABLE()等 |
| 正则表达式 | REGEXP操作符 | 新增REGEXP_REPLACE() |
| 生成随机UUID | 需自定义函数 | 原生UUID()函数 |
9. 调试技巧与错误排查
9.1 常见错误类型
- 日期越界错误:
SELECT DATE('2023-02-30');→ NULL - 字符串截断:
SUBSTRING('abc', 2, 10)→ 'bc'(不会报错) - 除零错误:
SELECT 1/0;→ NULL(5.7+版本)
9.2 函数调试方法
sql复制-- 分步验证法
SET @temp = '2023-07-20 14:30:45';
SELECT @temp AS original,
DATE(@temp) AS date_part,
TIME(@temp) AS time_part;
10. 最佳实践总结
- 函数嵌套原则:不超过3层嵌套,复杂逻辑建议用存储过程
- 时区陷阱:所有日期函数受@@time_zone影响,跨时区系统要显式设置
- 字符集问题:字符串函数结果依赖字段字符集,UTF8MB4是推荐选择
- NULL处理:绝大多数函数遇到NULL返回NULL,需用IFNULL()包裹
实际项目中,我习惯为常用函数组合创建视图或存储过程。例如每月初运行的报表生成脚本,会封装日期计算、字符串格式化等操作,既能复用代码又便于统一维护。