| 函数类别 | 主要用途 | 常用函数 |
|---|---|---|
| 聚合函数 | 对一组值执行计算并返回单个汇总结果,常用于统计分析 | count()、sum()、avg()、max()、min() |
| 字符串函数 | 处理文本数据,如拼接、截取、替换、格式化等操作 | concat()、concat_ws()、substr()、substring()、replace()、length()、trim()、upper()、lower() |
| 日期时间函数 | 用于日期和时间的提取、计算及格式转换 | new()、curdate()、date_add()、datediff()、timestampdiff()、date_format() |
| 数学函数 | 执行基本数学运算,如四舍五入、取整、求绝对值等 | round()、ceil()、floor()、abs()、mod() |
| 流程控制函数 | 实现条件判断逻辑,根据不同条件返回不同结果 | if()、case … when、ifnull()、coalesce() |
聚合函数详解
聚合函数通常与 GROUP BY 子句结合使用,以完成对分组数据的统计分析。
GROUP BY
COUNT()
COUNT():用于统计行的数量。其中 COUNT(*) 统计所有行,而 COUNT(字段名) 则仅统计该字段非空值的记录数。
COUNT(*)
COUNT(字段名)
SUM():对指定的数值型字段进行求和运算,忽略 NULL 值。
SUM()
AVG():计算某一数值字段的平均值,自动排除空值参与计算。
AVG()
MAX() 和 MIN():分别返回字段中的最大值和最小值,适用于数值、字符串以及日期类型的数据。
MAX() / MIN()
GROUP_CONCAT():将同一分组内的多个值连接成一个字符串,便于查看集合信息。
GROUP_CONCAT()
SELECT department_id, COUNT(*) AS emp_count, -- 部门员工总数 AVG(salary) AS avg_salary, -- 平均薪资水平 MAX(salary) AS top_salary, -- 最高薪资 GROUP_CONCAT(last_name) AS emp_names -- 所有员工姓氏合并显示 FROM employees GROUP BY department_id;
字符串函数应用
CONCAT():将两个或多个字符串合并为一个整体。
CONCAT(str1, str2, ...)
SELECT CONCAT(last_name, '(', first_name, ')') AS full_name FROM employees;
SUBSTR() 或 SUBSTRING():从指定位置开始截取子串,起始索引为1。
SUBSTR(str, start, [len])
SELECT SUBSTR('MySQL Database', 7, 4); -- 返回 'Data'
REPLACE():在原字符串中查找并替换特定内容。
REPLACE(str, from_str, to_str)
SELECT REPLACE('Hello World', 'World', 'MySQL'); -- 返回 'Hello MySQL'
LENGTH() 与 CHAR_LENGTH():LENGTH 返回字符串所占字节数(受字符集影响),CHAR_LENGTH 返回实际字符个数。
LENGTH(str)
-- 示例:'¥' 在 UTF8 编码下占用3个字节
SELECT LENGTH('¥'), CHAR_LENGTH('¥');
-- 结果:3, 1
原因在于当前数据库使用 UTF8 字符集,而某些特殊符号(如‘¥’)会占用多个字节存储空间。可通过以下命令查看字符集设置:
SHOW CREATE DATABASE 数据库名; -- 输出中可能包含:DEFAULT CHARACTER SET utf8
CHAR_LENGTH()
TRIM():去除字符串首尾的空格或指定字符。
TRIM([chars FROM] str)
SELECT TRIM(' example '); -- 返回 'example'
SELECT TRIM('x' FROM 'xxxHelloxxx'); -- 返回 'Hello'
UPPER():将字符串全部转为大写形式。
UPPER(str)
LOWER():将字符串全部转为小写形式。
LOWER(str)
日期与时间函数操作
NOW()、CURDATE()、CURTIME():分别获取当前的日期时间、仅日期部分、仅时间部分。
NOW() / CURDATE() / CURTIME()
DATE_ADD():对日期进行加减操作,支持多种时间单位。
DATE_ADD(date, INTERVAL expr unit) / DATE_SUB()
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY); -- 一周后的日期时间 SELECT CURDATE() - INTERVAL 1 MONTH; -- 一个月前的日期
DATEDIFF():计算两个日期之间的天数差(end_date - start_date)。
DATEDIFF(date1, date2)
date1 - date2
SELECT DATEDIFF('2024-01-01', '2023-12-25'); -- 返回 7
TIMESTAMPDIFF():计算两个日期之间相差的指定单位数量,可选择秒、分钟、小时、天等。
TIMESTAMPDIFF(UNIT, start_date, end_date)
SELECT TIMESTAMPDIFF(DAY, '2023-12-25', '2024-01-01'); -- 返回 7 SELECT TIMESTAMPDIFF(HOUR, start_date, end_date);
DATE_FORMAT():按照自定义格式输出日期时间。
DATE_FORMAT(date, format)
SELECT DATE_FORMAT(NOW(), '%Y年%m月%d日 %H:%i:%s'); -- 如 '2024年01月01日 14:30:00'
EXTRACT():从日期中提取年、月、日、小时等组成部分。
YEAR() / MONTH() / DAY()
流程控制函数说明
流程控制函数赋予 SQL 查询语句条件判断的能力,使其能够根据不同的数据状态返回相应的结果。
IF(condition, value_if_true, value_if_false)在 SQL 查询中,条件判断是实现数据筛选和分类的重要手段。通过简单的条件表达式,可以完成基础的逻辑判断操作。
SELECT name, salary, IF(salary > 8000, '高', '普通') AS salary_level FROM employees;
CASE ... WHEN
对于更复杂的业务需求,可以使用 CASE 表达式来实现多分支条件处理。例如,根据学生的分数范围返回对应的等级:
SELECT name, CASE WHEN score >= 90 THEN '优秀' WHEN score >= 60 THEN '及格' ELSE '不及格' END AS grade FROM students;
IFNULL() / COALESCE()
在处理缺失或空值时,SQL 提供了多种函数来应对 NULL 值的情况。
NULL
当某个字段的值为 NULL 时,可以通过特定函数进行替换处理。
IFNULL(expr1, expr2)
如果表达式的值为 NULL,则返回指定的默认值;否则返回该表达式本身的值。
expr1
该逻辑可用于从参数列表中依次查找第一个非 NULL 的值并返回。
expr2
COALESCE
示例如下:
SELECT name, IFNULL(bonus, 0) AS bonus FROM sales; -- 将 NULL 的奖金视为 0 SELECT COALESCE(NULL, NULL, 'Fallback'); -- 返回第一个非 NULL 值 'Fallback'
使用函数时的注意事项
索引的影响
在查询条件中对字段应用函数(如对列使用 UPPER() 或 DATE() 等操作)可能导致数据库无法有效利用索引,从而降低查询效率。若此类查询频繁执行,建议改用范围查询或其他可索引的方式替代。
WHERE YEAR(date_column) = 2024
例如,使用大于、小于等比较运算符配合具体值进行范围筛选,有助于保留索引优势。
WHERE date_column BETWEEN '2024-01-01' AND '2024-12-31'
WHERE 与 HAVING 的区别
WHERE
WHERE 子句用于在分组之前过滤数据行,其条件作用于原始记录,且不能包含聚合函数。
HAVING
HAVING 子句则用于对分组后的结果进行筛选,允许在条件中使用 AVG、SUM 等聚合函数。
以下为正确使用示例:
-- 正确:使用 HAVING 过滤分组后的聚合结果 SELECT department_id, AVG(salary) FROM employees GROUP BY department_id HAVING AVG(salary) > 8000; -- 正确:使用 WHERE 在分组前筛选符合条件的行 SELECT department_id, AVG(salary) FROM employees WHERE salary > 5000 -- 先过滤出薪资高于 5000 的员工 GROUP BY department_id;


雷达卡


京公网安备 11010802022788号







