MySQL函数

掌握MySQL内置函数的使用方法

MySQL函数概述

MySQL提供了丰富的内置函数,用于处理数据、执行计算和转换数据格式。函数可以简化SQL语句,提高开发效率。

函数的重要性

MySQL函数能够简化复杂的SQL操作,提高查询效率,增强数据处理能力。合理使用函数可以减少应用程序代码量,将数据处理逻辑下推到数据库层面。

函数分类

  • 字符串函数 - 处理文本数据
  • 数值函数 - 执行数学运算
  • 日期和时间函数 - 处理日期和时间
  • 聚合函数 - 对一组值执行计算并返回单个值
  • 控制流函数 - 实现条件逻辑
  • 系统信息函数 - 返回数据库系统信息
  • 加密函数 - 提供数据加密功能
  • JSON函数 - 处理JSON格式数据
  • 转换函数 - 数据类型转换

字符串函数

字符串函数用于操作文本数据,如连接、截取、替换等。这些函数对于数据清洗、格式化和转换非常有用。

常用字符串函数

函数 描述 示例 返回值
CONCAT() 连接字符串 CONCAT('Hello', ' ', 'World') 'Hello World'
SUBSTRING() 截取子字符串 SUBSTRING('MySQL', 1, 2) 'My'
LENGTH() 返回字符串长度 LENGTH('MySQL') 5
UPPER() / LOWER() 转换为大写/小写 UPPER('mysql') 'MYSQL'
TRIM() 去除首尾空格 TRIM(' MySQL ') 'MySQL'
REPLACE() 替换字符串 REPLACE('MySQL', 'SQL', 'Database') 'MyDatabase'
LEFT() / RIGHT() 返回左/右侧指定长度字符串 LEFT('MySQL', 2) 'My'
LOCATE() 返回子字符串位置 LOCATE('SQL', 'MySQL') 3
REVERSE() 反转字符串 REVERSE('MySQL') 'LQSyM'
FORMAT() 格式化数字为字符串 FORMAT(12345.6789, 2) '12,345.68'

更多字符串函数

  • SUBSTRING_INDEX(str, delim, count):按分隔符截取子串。
  • REGEXP_REPLACE(str, pattern, replace):使用正则表达式替换。
  • REGEXP_INSTR(str, pattern):返回正则表达式匹配的位置。
SQL示例
-- 提取域名
SELECT email, SUBSTRING_INDEX(email, '@', -1) AS domain FROM users;

-- 正则表达式替换
SELECT REGEXP_REPLACE(description, '[0-9]+', '[REDACTED]') FROM products;

字符串函数示例

SQL示例
-- 连接字符串
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees;

-- 截取字符串
SELECT SUBSTRING(email, 1, 5) AS username FROM users;

-- 替换字符串
SELECT REPLACE(description, 'old', 'new') FROM products;

-- 格式化数字
SELECT product_name, FORMAT(price, 2) AS formatted_price FROM products;

-- 提取域名
SELECT email, SUBSTRING(email, LOCATE('@', email) + 1) AS domain FROM users;

数值函数

数值函数用于执行数学运算,如四舍五入、绝对值、取整等。这些函数对于财务计算、统计分析等场景非常有用。

常用数值函数

函数 描述 示例 返回值
ROUND() 四舍五入 ROUND(123.456, 2) 123.46
CEIL() / FLOOR() 向上/向下取整 CEIL(123.45) 124
ABS() 绝对值 ABS(-123) 123
POWER() 幂运算 POWER(2, 3) 8
MOD() 取模运算 MOD(10, 3) 1
RAND() 生成随机数 RAND() 0.0-1.0之间的随机数
SQRT() 平方根 SQRT(16) 4
EXP() 指数函数 EXP(1) 2.718281828459045
LOG() / LOG10() 自然对数/常用对数 LOG(EXP(1)) 1
SIN() / COS() / TAN() 三角函数 SIN(PI()/2) 1

更多数值函数

  • TRUNCATE(num, decimals):截断小数位,不进行四舍五入。
  • RADIANS(deg) / DEGREES(rad):角度弧度转换。
SQL示例
SELECT TRUNCATE(123.456, 2);  -- 123.45
SELECT RADIANS(180);  -- 3.14159

数值函数示例

SQL示例
-- 四舍五入
SELECT ROUND(price, 2) AS rounded_price FROM products;

-- 计算平均值并四舍五入
SELECT ROUND(AVG(salary), 0) AS avg_salary FROM employees;

-- 随机排序
SELECT * FROM products ORDER BY RAND() LIMIT 5;

-- 计算几何平均值
SELECT EXP(AVG(LOG(price))) AS geometric_mean FROM products;

日期和时间函数

日期和时间函数用于处理日期和时间数据,如提取日期部分、计算日期差等。这些函数对于时间序列分析、报表生成等场景非常重要。

常用日期函数

函数 描述 示例 返回值
NOW() 返回当前日期和时间 NOW() 2023-10-15 14:30:00
CURDATE() / CURTIME() 返回当前日期/时间 CURDATE() 2023-10-15
DATE() / TIME() 提取日期/时间部分 DATE('2023-10-15 14:30:00') 2023-10-15
YEAR() / MONTH() / DAY() 提取年/月/日 YEAR('2023-10-15') 2023
DATEDIFF() 计算日期差 DATEDIFF('2023-10-20', '2023-10-15') 5
DATE_ADD() / DATE_SUB() 日期加减 DATE_ADD('2023-10-15', INTERVAL 7 DAY) 2023-10-22
DAYNAME() / MONTHNAME() 返回星期/月份名称 DAYNAME('2023-10-15') 'Sunday'
WEEK() / QUARTER() 返回周数/季度 WEEK('2023-10-15') 41
DATE_FORMAT() 格式化日期 DATE_FORMAT(NOW(), '%Y-%m-%d') '2023-10-15'
STR_TO_DATE() 字符串转日期 STR_TO_DATE('15,10,2023', '%d,%m,%Y') 2023-10-15

更多日期函数

  • TIMESTAMPDIFF(unit, datetime1, datetime2):计算两个日期时间之间的差值,单位可指定。
  • LAST_DAY(date):返回月份的最后一天。
  • MAKEDATE(year, dayofyear):根据年份和天数生成日期。
SQL示例
SELECT TIMESTAMPDIFF(YEAR, birth_date, CURDATE()) AS age FROM users;
SELECT LAST_DAY(CURDATE());  -- 当月最后一天

日期函数示例

SQL示例
-- 获取当前日期和时间
SELECT NOW() AS current_datetime;

-- 提取年份
SELECT YEAR(birth_date) AS birth_year FROM employees;

-- 计算年龄
SELECT name, YEAR(CURDATE()) - YEAR(birth_date) AS age FROM employees;

-- 查询最近7天的订单
SELECT * FROM orders 
WHERE order_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY);

-- 格式化日期
SELECT order_id, DATE_FORMAT(order_date, '%Y年%m月%d日') AS formatted_date FROM orders;

时区转换

使用 CONVERT_TZ() 可以将日期时间从一个时区转换到另一个时区。

SQL示例
SELECT CONVERT_TZ(NOW(), 'SYSTEM', 'America/New_York');

聚合函数

聚合函数对一组值执行计算并返回单个值,通常与GROUP BY子句一起使用。这些函数对于数据汇总和统计分析至关重要。

常用聚合函数

函数 描述 示例 返回值
COUNT() 计算行数 COUNT(*) 记录总数
SUM() 计算总和 SUM(salary) 薪资总和
AVG() 计算平均值 AVG(salary) 平均薪资
MAX() / MIN() 返回最大/最小值 MAX(salary) 最高薪资
GROUP_CONCAT() 将多行合并为字符串 GROUP_CONCAT(name) 所有姓名的逗号分隔列表
VARIANCE() / STDDEV() 计算方差/标准差 VARIANCE(salary) 薪资方差
BIT_AND() / BIT_OR() 位与/位或运算 BIT_AND(permissions) 权限的位与结果

聚合函数示例

SQL示例
-- 统计员工总数
SELECT COUNT(*) AS total_employees FROM employees;

-- 计算各部门平均薪资
SELECT department, AVG(salary) AS avg_salary 
FROM employees 
GROUP BY department;

-- 获取每个部门的员工姓名列表
SELECT department, GROUP_CONCAT(name) AS employees 
FROM employees 
GROUP BY department;

-- 计算薪资统计信息
SELECT 
    COUNT(*) AS employee_count,
    AVG(salary) AS average_salary,
    MIN(salary) AS min_salary,
    MAX(salary) AS max_salary,
    STDDEV(salary) AS salary_stddev
FROM employees;
使用建议:聚合函数通常与GROUP BY子句一起使用,但COUNT(*)也可以单独使用统计总行数。注意NULL值在聚合函数中的处理方式:COUNT(column)会忽略NULL值,而COUNT(*)不会。

控制流函数

控制流函数用于在SQL中实现条件逻辑,类似于编程语言中的if-else语句。这些函数对于数据转换和条件处理非常有用。

常用控制流函数

函数 描述 示例 返回值
IF() 条件判断 IF(score >= 60, '及格', '不及格') '及格' 或 '不及格'
CASE 多条件判断 CASE WHEN score >= 90 THEN '优秀' ... END 根据条件返回不同值
IFNULL() / COALESCE() 处理NULL值 IFNULL(salary, 0) salary或0
NULLIF() 比较两个表达式 NULLIF(column1, column2) NULL或column1

控制流函数示例

SQL示例
-- 使用IF函数
SELECT name, score, 
       IF(score >= 60, '及格', '不及格') AS result 
FROM students;

-- 使用CASE语句
SELECT name, score,
       CASE
           WHEN score >= 90 THEN '优秀'
           WHEN score >= 80 THEN '良好'
           WHEN score >= 60 THEN '及格'
           ELSE '不及格'
       END AS grade
FROM students;

-- 处理NULL值
SELECT name, IFNULL(bonus, 0) AS bonus_amount 
FROM employees;

-- 使用COALESCE处理多个可能的NULL值
SELECT name, COALESCE(phone, mobile, '无联系方式') AS contact 
FROM customers;

-- 搜索式CASE语句
SELECT product_name, category_id,
       CASE category_id
           WHEN 1 THEN '电子产品'
           WHEN 2 THEN '家居用品'
           WHEN 3 THEN '服装'
           ELSE '其他'
       END AS category_name
FROM products;

加密函数

MySQL提供加密函数用于保护敏感数据。

SQL示例
-- MD5哈希
SELECT MD5('password123');

-- SHA1/SHA2哈希
SELECT SHA1('password123');
SELECT SHA2('password123', 256);

-- AES加密解密
SET @key = 'my_secret_key_32_bytes_long_123';
SELECT AES_ENCRYPT('sensitive_data', @key);
SELECT AES_DECRYPT(encrypted_data, @key) FROM secure_table;
安全提示:MD5和SHA1已不再安全,推荐使用SHA2或更高级的加密算法。对于密码存储,应使用加盐哈希(如结合 RAND()SHA2)。

转换函数

用于数据类型转换。

SQL示例
-- CAST转换
SELECT CAST('123' AS UNSIGNED);
SELECT CAST(123.45 AS CHAR);
SELECT CAST('2023-10-15' AS DATE);

-- CONVERT转换
SELECT CONVERT('123', UNSIGNED);
SELECT CONVERT(123.45, CHAR);
SELECT CONVERT('2023-10-15', DATE);

系统信息函数

系统信息函数用于获取数据库和连接的相关信息,对于调试和监控非常有用。

常用系统信息函数

函数 描述 示例
VERSION() 返回MySQL版本 VERSION()
DATABASE() 返回当前数据库名 DATABASE()
USER() 返回当前用户名 USER()
CONNECTION_ID() 返回连接ID CONNECTION_ID()
LAST_INSERT_ID() 返回最后插入的AUTO_INCREMENT值 LAST_INSERT_ID()
ROW_COUNT() 返回受影响的行数 ROW_COUNT()

JSON 函数详解

MySQL 5.7+ 提供了丰富的JSON函数,用于高效处理JSON数据。

SQL示例
-- 创建JSON数据
SELECT JSON_OBJECT('name', 'John', 'age', 30);
SELECT JSON_ARRAY(1, 2, 'three');

-- 提取JSON数据
SELECT data, data->'$.name', JSON_EXTRACT(data, '$.address.city') FROM customers;

-- 修改JSON数据
UPDATE customers SET data = JSON_SET(data, '$.age', 31, '$.email', 'john@example.com');
UPDATE customers SET data = JSON_INSERT(data, '$.phone', '123456');  -- 仅当路径不存在时插入
UPDATE customers SET data = JSON_REPLACE(data, '$.age', 32);  -- 仅当路径存在时替换
UPDATE customers SET data = JSON_REMOVE(data, '$.temp_field');

-- JSON数组操作
SELECT JSON_ARRAY_APPEND('[1,2]', '$', 3);  -- [1,2,3]
SELECT JSON_SEARCH(data, 'one', 'John') FROM customers;

-- JSON_TABLE: 将JSON数据转换为关系表(MySQL 8.0+)
SELECT jt.*
FROM customers,
JSON_TABLE(
    data,
    '$' COLUMNS(
        name VARCHAR(50) PATH '$.name',
        age INT PATH '$.age',
        NESTED PATH '$.address' COLUMNS(
            city VARCHAR(50) PATH '$.city'
        )
    )
) AS jt;

用户自定义函数 (UDF)

MySQL允许使用C/C++编写用户自定义函数,扩展内置函数库。创建UDF需要编译动态库并在MySQL中注册,适用于高性能、复杂计算的场景。

注意:UDF的创建需要文件系统权限和MySQL的插件支持,普通开发环境中使用较少。对于一般逻辑,推荐使用存储过程或内置函数。

函数性能优化建议

  • 避免在WHERE子句中对列使用函数,这会使索引失效
  • 对于复杂的计算,考虑在应用程序层面处理
  • 合理使用存储过程封装复杂的函数逻辑
  • 注意函数的返回值类型,避免隐式类型转换
  • 使用EXPLAIN分析包含函数的查询性能

下一步学习

掌握了MySQL函数后,您可以继续学习: