1. MySQL函数概述
MySQL作为最流行的关系型数据库之一,提供了丰富的内置函数来简化数据操作和处理。这些函数可以大致分为以下几类:
- 字符串函数:用于处理文本数据
- 数值函数:用于数学运算
- 日期和时间函数:用于处理日期和时间值
- 聚合函数:用于对多行数据进行计算
- 控制流函数:用于条件判断
- 系统信息函数:返回数据库和系统信息
这些函数可以直接在SQL语句中使用,极大地增强了SQL的表达能力和灵活性。下面我们将详细介绍各类常用函数的具体用法和实际应用场景。
2. 字符串处理函数
2.1 基本字符串操作
MySQL提供了多种字符串处理函数,以下是几个最常用的:
sql复制-- 连接字符串
SELECT CONCAT('Hello', ' ', 'World'); -- 输出: Hello World
-- 转换为小写/大写
SELECT LOWER('MySQL'), UPPER('mysql');
-- 去除空格
SELECT TRIM(' MySQL '), LTRIM(' MySQL'), RTRIM('MySQL ');
-- 获取字符串长度
SELECT LENGTH('MySQL'); -- 字节数
SELECT CHAR_LENGTH('MySQL'); -- 字符数
注意:LENGTH()返回的是字节数,对于多字节字符(如中文),它与CHAR_LENGTH()的结果会不同。在处理UTF-8编码的中文时,一个中文字符通常占3个字节。
2.2 字符串截取与定位
sql复制-- 截取子字符串
SELECT SUBSTRING('MySQL Functions', 7, 8); -- 从第7个字符开始截取8个字符,输出: Functions
-- 定位子字符串位置
SELECT LOCATE('SQL', 'MySQL SQL'); -- 返回3,表示'SQL'首次出现的位置
-- 左右截取
SELECT LEFT('MySQL', 2); -- 输出: My
SELECT RIGHT('MySQL', 3); -- 输出: SQL
2.3 字符串替换与格式化
sql复制-- 字符串替换
SELECT REPLACE('I use Oracle', 'Oracle', 'MySQL'); -- 输出: I use MySQL
-- 格式化字符串
SELECT FORMAT(1234567.89, 2); -- 输出: 1,234,567.89
-- 重复字符串
SELECT REPEAT('MySQL ', 3); -- 输出: MySQL MySQL MySQL
3. 数值处理函数
3.1 基本数学运算
sql复制-- 四舍五入
SELECT ROUND(3.14159, 2); -- 输出: 3.14
-- 向上/向下取整
SELECT CEIL(3.14), FLOOR(3.99); -- 输出: 4, 3
-- 绝对值
SELECT ABS(-10); -- 输出: 10
-- 随机数
SELECT RAND(); -- 返回0到1之间的随机浮点数
3.2 高级数学函数
sql复制-- 幂运算
SELECT POWER(2, 10); -- 2的10次方,输出: 1024
-- 平方根
SELECT SQRT(16); -- 输出: 4
-- 对数
SELECT LOG(10, 100); -- 以10为底100的对数,输出: 2
-- 三角函数
SELECT SIN(PI()/2), COS(0), TAN(PI()/4);
3.3 数值比较与处理
sql复制-- 取模运算
SELECT MOD(10, 3); -- 输出: 1
-- 符号判断
SELECT SIGN(-5), SIGN(0), SIGN(5); -- 输出: -1, 0, 1
-- 截断小数位
SELECT TRUNCATE(3.14159, 2); -- 输出: 3.14
4. 日期和时间函数
4.1 获取当前日期和时间
sql复制-- 当前日期和时间
SELECT NOW(); -- 格式: YYYY-MM-DD HH:MM:SS
SELECT CURRENT_DATE(), CURRENT_TIME();
-- 时间戳
SELECT UNIX_TIMESTAMP(); -- 返回Unix时间戳
SELECT FROM_UNIXTIME(UNIX_TIMESTAMP()); -- 时间戳转日期
4.2 日期时间提取与计算
sql复制-- 提取日期部分
SELECT DATE(NOW()); -- 只返回日期部分
-- 提取年、月、日等
SELECT YEAR(NOW()), MONTH(NOW()), DAY(NOW());
SELECT HOUR(NOW()), MINUTE(NOW()), SECOND(NOW());
-- 日期加减
SELECT DATE_ADD(NOW(), INTERVAL 1 DAY); -- 加1天
SELECT DATE_SUB(NOW(), INTERVAL 1 MONTH); -- 减1个月
-- 日期差
SELECT DATEDIFF('2023-12-31', '2023-01-01'); -- 输出: 364
4.3 日期格式化
sql复制-- 日期格式化
SELECT DATE_FORMAT(NOW(), '%Y年%m月%d日 %H时%i分%s秒'); -- 中文格式
SELECT DATE_FORMAT(NOW(), '%W, %M %d, %Y'); -- 英文格式: Wednesday, July 19, 2023
-- 字符串转日期
SELECT STR_TO_DATE('2023-07-19', '%Y-%m-%d');
5. 聚合函数
5.1 基本聚合函数
sql复制-- 计数
SELECT COUNT(*) FROM employees;
-- 求和
SELECT SUM(salary) FROM employees;
-- 平均值
SELECT AVG(salary) FROM employees;
-- 最大值/最小值
SELECT MAX(salary), MIN(salary) FROM employees;
5.2 分组聚合
sql复制-- 按部门统计平均工资
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id;
-- 使用HAVING筛选分组结果
SELECT department_id, AVG(salary)
FROM employees
GROUP BY department_id
HAVING AVG(salary) > 5000;
5.3 高级聚合技巧
sql复制-- 使用WITH ROLLUP生成小计
SELECT department_id, job_id, SUM(salary)
FROM employees
GROUP BY department_id, job_id WITH ROLLUP;
-- 使用GROUP_CONCAT连接分组值
SELECT department_id, GROUP_CONCAT(last_name)
FROM employees
GROUP BY department_id;
6. 控制流函数
6.1 条件判断
sql复制-- IF函数
SELECT name, salary, IF(salary > 5000, '高薪', '普通') AS salary_level
FROM employees;
-- CASE WHEN表达式
SELECT name, salary,
CASE
WHEN salary > 10000 THEN '高级'
WHEN salary > 5000 THEN '中级'
ELSE '初级'
END AS level
FROM employees;
6.2 空值处理
sql复制-- 处理NULL值
SELECT name, IFNULL(commission_pct, 0) AS commission
FROM employees;
-- 使用COALESCE返回第一个非NULL值
SELECT COALESCE(NULL, NULL, 'default'); -- 输出: default
6.3 其他控制函数
sql复制-- NULLIF: 两值相等返回NULL
SELECT NULLIF(1, 1), NULLIF(1, 2); -- 输出: NULL, 1
-- 使用IFNULL或COALESCE设置默认值
SELECT name, COALESCE(phone, '未提供') AS contact
FROM customers;
7. 系统信息函数
7.1 数据库信息
sql复制-- 当前数据库
SELECT DATABASE();
-- 数据库版本
SELECT VERSION();
-- 当前用户
SELECT USER();
-- 连接ID
SELECT CONNECTION_ID();
7.2 系统状态信息
sql复制-- 最后插入的ID
SELECT LAST_INSERT_ID();
-- 影响行数
SELECT ROW_COUNT();
-- 系统变量
SELECT @@version, @@hostname;
7.3 性能相关函数
sql复制-- 查询执行时间
SELECT BENCHMARK(1000000, MD5('test'));
-- 获取UUID
SELECT UUID();
-- 获取自增ID值
SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'your_table';
8. 函数使用技巧与最佳实践
8.1 性能优化建议
-
避免在WHERE条件中使用函数:这会导致索引失效
sql复制-- 不推荐 (索引失效) SELECT * FROM orders WHERE YEAR(order_date) = 2023; -- 推荐 (可以使用索引) SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31'; -
减少函数嵌套:多层嵌套会影响性能且难以维护
-
注意函数的数据类型转换:隐式转换可能导致性能问题
8.2 常见问题解决
-
时区问题:
sql复制-- 设置会话时区 SET time_zone = '+08:00'; -- 转换时区 SELECT CONVERT_TZ(NOW(), 'UTC', 'Asia/Shanghai'); -
字符集问题:
sql复制-- 转换字符集 SELECT CONVERT('中文' USING utf8mb4); -- 检查字符集 SELECT CHARSET('中文'); -
函数结果缓存:
sql复制-- NOW()在语句执行时只计算一次 SELECT NOW(), SLEEP(2), NOW(); -- 两个NOW()值相同 -- SYSDATE()每次调用都重新计算 SELECT SYSDATE(), SLEEP(2), SYSDATE(); -- 两个值不同
8.3 自定义函数
MySQL还允许创建自定义函数:
sql复制-- 创建简单函数
DELIMITER //
CREATE FUNCTION calculate_tax(salary DECIMAL(10,2))
RETURNS DECIMAL(10,2)
DETERMINISTIC
BEGIN
DECLARE tax DECIMAL(10,2);
IF salary <= 5000 THEN
SET tax = 0;
ELSEIF salary <= 10000 THEN
SET tax = salary * 0.1;
ELSE
SET tax = salary * 0.2;
END IF;
RETURN tax;
END //
DELIMITER ;
-- 使用自定义函数
SELECT name, salary, calculate_tax(salary) AS tax FROM employees;
在实际项目中,合理使用MySQL函数可以显著提高开发效率和查询能力。掌握这些函数的特性和适用场景,能够帮助开发者编写更高效、更简洁的SQL语句。
