文章目录
- [一: 聚合函数](#一: 聚合函数)
-
- 1.计数函数 (COUNT)
- 2.求和函数 (SUM)
- 3.平均值函数 (AVG)
- [4. 最大值与最小值函数 (MAX / MIN)](#4. 最大值与最小值函数 (MAX / MIN))
- [二: 分组查询 (GROUP BY) 与 结果筛选 (HAVING)](#二: 分组查询 (GROUP BY) 与 结果筛选 (HAVING))
- [三: 日期函数](#三: 日期函数)
-
- 1.获取当前时间
- 2.日期提取与转换
- 3.日期的加减运算(实战核心)
- [4.计算日期差:DATEDIFF(expr1, expr2)](#4.计算日期差:DATEDIFF(expr1, expr2))
- [四: 字符串处理函数](#四: 字符串处理函数)
- [五: 数学函数](#五: 数学函数)
-
- 1.ABS(X)
- [2.CEIL(X) / CEILING(X)](#2.CEIL(X) / CEILING(X))
- 3.FLOOR(X)
- 4.ROUND(X,D)
- 5.RAND()
- [六: 其他常用函数](#六: 其他常用函数)
-
- [1.VERSION( )](#1.VERSION( ))
- [2.DATABASE( )](#2.DATABASE( ))
- [3.USER( )](#3.USER( ))
- 4.MD5(str)
- 5.IFNULL(val1,val2)

文章作者:当战神遇到编程
文章专栏:MySQL
欢迎大家点赞👍评论📝收藏⭐文章



一: 聚合函数
聚合函数是为了进行聚合查询,聚合查询就是就是进行"行与行之间的运算"
以下这些常用函数都只能接受一个参数
| 函数 | 作用 |
|---|---|
| COUNT(expr) | 统计数量 |
| SUM(expr) | 求和 |
| AVG(expr) | 平均值 |
| MAX(expr) | 最大值 |
| MIN(expr) | 最小值 |
准备测试表
员工表 emp
sql
CREATE TABLE emp(
emp_id INT,
name VARCHAR(20),
dept_id INT,
salary DECIMAL(10,2)
);
部门表 dept
sql
CREATE TABLE dept(
dept_id INT,
dept_name VARCHAR(20)
);
1.计数函数 (COUNT)
COUNT() 用于统计结果集中记录的行数。
sql
-- 方式 A:统计总行数(包含 NULL 值)
SELECT COUNT(*) FROM emp;
-- 方式 B:统计指定列的有值行数(忽略 NULL 值)
SELECT COUNT(salary) FROM emp;
2.求和函数 (SUM)
SUM() 用于计算数值列的总和。
(1) 针对单个字段求和
这是最基础的用法,统计某一列的总数。
sql
-- 统计公司所有人的基本工资总和
SELECT SUM(salary) FROM emp;
- 特点 :它会自动忽略 NULL 值(不计入总和)。
(2) 针对多个字段(或表达式)求和
有时候我们需要统计的不是某一个列,而是几个列计算后的总结果。
sql
-- 统计公司"实发工资"的总和(基本工资 + 奖金)
SELECT SUM(salary + bonus) FROM emp;
-
核心逻辑
1.数据库会先计算每一行的 salary + bonus。
2.然后再将每一行算出的结果进行累加。
-
避坑提醒(NULL 陷阱) :
○ 在 SQL 中,任何数值 + NULL 的结果都是 NULL。
○ 如果某员工有 salary 但 bonus 是 NULL,那么 salary + bonus 的结果就是 NULL,这条数据就不会被计入总和。
-
非数值处理:只能作用于数值类型(数字)。对字符串求和没有意义,通常结果为 0。
3.平均值函数 (AVG)
AVG(expr) 用于计算一组数值的平均值。
sql
-- 统计公司所有人的平均工资
SELECT AVG(salary) FROM emp;
-- 统计公司所有人的平均总收入(基本工资 + 奖金)
SELECT AVG(salary + bonus) FROM emp;
深度详细拆解(必看要点)
-
结果支持小数
○ 特点:AVG 的计算结果通常会自动转换为浮点数(小数)。
-
NULL 的陷阱(最核心区别) :
○ AVG 在计算时会同时忽略分子和分母中的 NULL 。
○ 举例:有 3 个人,工资分别是 1000, 2000, NULL。
○ AVG 的计算逻辑是 (1000 + 2000) / 2 = 1500。
-
非数值处理:只能作用于数值类型(数字)。对字符串求平均值没有意义,通常结果为 0。
4. 最大值与最小值函数 (MAX / MIN)
MAX(expr) 和 MIN(expr) 分别用于找出一组值中的最高分和最低分。
sql
-- 找出公司里的最高工资和最低工资
SELECT MAX(salary), MIN(salary) FROM emp;
-- 找出最高的"个人净收入"(工资 - 扣款)
SELECT MAX(salary - deduction) FROM emp;
深度详细拆解
-
字符串:按字母顺序排列(A 最小,Z 最大)。MAX(name) 会返回字母表靠后的名字。
-
NULL 的处理 :
○ 它们都会自动忽略 NULL 。
○ 如果一列全是 NULL,结果返回 NULL。
二: 分组查询 (GROUP BY) 与 结果筛选 (HAVING)
分组查询是聚合查询的核心环节,它负责将全表数据按指定维度进行"分类汇总"。
1.基础案例:按维度统计
sql
-- 案例 1:按部门统计人数
-- 注意:COUNT(name) 会忽略名字为 NULL 的记录
SELECT dept_id, COUNT(name) FROM emp GROUP BY dept_id;
-- 案例 2:按部门统计平均工资
SELECT dept_id, AVG(salary) FROM emp GROUP BY dept_id;
2.核心铁律:SELECT 的限制
在使用 GROUP BY 时,SELECT 后面的普通字段必须出现在 GROUP BY 子句中。
- 逻辑解释:分组后,一组对应一行结果。如果某字段(如姓名)在组内不唯一,数据库无法确定显示哪一个,因此必须按该字段分组或对其使用聚合函数。
3.分组后的筛选:HAVING
当我们需要对聚合后的统计结果进行过滤时(比如:只看人数 > 1 的部门),必须使用 HAVING。
sql
-- 查询人数大于 1 的部门
SELECT dept_id, COUNT(*) AS total FROM emp GROUP BY dept_id HAVING COUNT(*) > 1;
WHERE 与 HAVING 的本质区别
| 子句 | 执行时机 | 作用对象 | 备注 |
|---|---|---|---|
| WHERE | 分组前 | 筛选原始数据 | 决定哪些行能进入分组环节 |
| HAVING | 分组后 | 筛选分组结果 | 决定哪些组能出现在最终结果中 |
4.综合实战:先筛选,后分组
在实际业务中,我们通常需要先排除不符合条件的原始数据,再进行统计。
sql
-- 需求:先筛选工资 > 6000 的员工,再按部门统计人数
SELECT dept_id, COUNT(*) FROM emp WHERE salary > 6000 GROUP BY dept_id;
5.SQL 逻辑执行顺序
- FROM:定位表数据。
- WHERE:对原始行进行初次过滤。
- GROUP BY:将剩下的行分堆。
- HAVING:对分好的堆进行过滤。
- SELECT:提取字段、计算表达式、计算聚合函数、起别名。
- ORDER BY:对最终结果进行排序。
- LIMIT:最后一切两半,取指定行数。
三: 日期函数
1.获取当前时间
这类函数不需要参数,直接调用即可获取数据库服务器的当前时钟。
| 函数 | 返回值示例 | 说明 |
|---|---|---|
| CURDATE( ) | 2023-10-27 | 仅日期 (Current Date) |
| CURTIME( ) | 14:30:05 | 仅时间 (Current Time) |
| NOW( ) | 2023-10-27 14:30:05 | 日期 + 时间(最常用) |
场景一:直接查看系统时间
sql
-- 一次性查看日期、时间、以及完整的时间戳
SELECT CURDATE(), CURTIME(), NOW();
场景二:插入数据时自动记录时间
这是最常用的场景。比如有一个新用户注册,你需要记录他注册的精确瞬间。
sql
-- 假设表名叫 users,有一个字段叫 registration_time
INSERT INTO users (username, registration_time) VALUES ('张三', NOW());
- 意义: 使用 NOW() 可以确保记录下的是数据库服务器接收到请求的那一秒,非常精准。
2.日期提取与转换
当你有一个完整的"日期时间"字符串,但只需要其中一部分时使用。
- DATE(expr):
○ 作用 :强行切掉时间部分,只留日期。
○ 场景: 比如记录是 2023-10-27 14:30:05,执行 DATE() 后得到 2023-10-27。
3.日期的加减运算(实战核心)
这是日期处理中最难也最强大的部分,使用了特殊的 INTERVAL(间隔)语法。
- ADDDATE(date, INTERVAL expr unit)(加法):
○ ELECT ADDDATE(NOW(), INTERVAL 7 DAY); ------ 获取 7 天后 的时间。 - SUBDATE(date, INTERVAL expr unit)(减法):
○ SELECT SUBDATE(NOW(), INTERVAL 1 MONTH); ------ 获取 1 个月前 的时间(常用于统计上月报表)。
注意: unit 可以是 DAY, MONTH, YEAR, HOUR 等。
4.计算日期差:DATEDIFF(expr1, expr2)
- 计算逻辑:expr1 - expr2。
- 单位 :固定返回天数。
- 注意顺序:
○ DATEDIFF('2023-10-01', '2023-10-05') 结果是 -4 。
○ 如果第一个日期比第二个早,结果就是负数。
四: 字符串处理函数
1.获取长度
(1) CHAR_LENGTH(str)
返回字符串的 字符个数(一个汉字算 1 个字符)
sql
SELECT CHAR_LENGTH('hello'); -- 5
SELECT CHAR_LENGTH('你好'); -- 2
(2) LENGTH(str)
返回字符串占用的 字节数
sql
SELECT LENGTH('hello'); -- 5
SELECT LENGTH('你好'); -- 6 (UTF8下一个汉字3字节)
2.字符串拼接
(1) CONCAT(str1,str2,...)
直接拼接多个字符串
sql
SELECT CONCAT('张','三');
-- 张三
sql
SELECT CONCAT(name,'-',age) FROM student;
(2) CONCAT_WS(sep,str1,str2,...)
按指定分隔符拼接
sql
SELECT CONCAT_WS('-', '2026','04','22');
-- 2026-04-22
3.大小写转换
(1) LOWER(str) / LCASE(str)
转小写
sql
SELECT LOWER('HELLO');
-- hello
(2) UPPER(str) / UCASE(str)
转大写
sql
SELECT UPPER('hello');
-- HELLO
4.截取字符串(重点)
(1) SUBSTR(str,pos,len)
从指定位置开始截取 len 个字符
sql
SELECT SUBSTR('abcdef',2,3);
-- bcd
说明:
- 下标从 1 开始
- pos = 起始位置
常见场景:手机号隐藏
sql
SELECT CONCAT(SUBSTR(phone,1,3),'****',SUBSTR(phone,8,4)) FROM user;
5.替换字符串(重点)
(1) REPLACE(str,old,new)
sql
SELECT REPLACE('I like java','java','mysql');
-- I like mysql
批量修改数据
sql
UPDATE user SET address = REPLACE(address,'北京','上海');
6.左右截取
(1) LEFT(str,len)
取左边 len 个字符
sql
SELECT LEFT('abcdef',3);
-- abc
(2) RIGHT(str,len)
取右边 len 个字符
sql
SELECT RIGHT('abcdef',2);
-- ef
7.去空格(高频)
(1) TRIM(str)
去除两边空格
sql
SELECT TRIM(' hello ');
-- hello
(2) LTRIM(str)
去左边空格
sql
SELECT LTRIM(' hello');
(3) RTRIM(str)
去右边空格
sql
SELECT RTRIM('hello ');
8.查找字符串位置
INSTR(str,substr)
返回子串第一次出现的位置(从1开始)
sql
SELECT INSTR('abcdef','cd');
-- 3
找不到返回:
sql
0
五: 数学函数
1.ABS(X)
返回 X 的绝对值。
sql
SELECT ABS(-10);
-- 10
2.CEIL(X) / CEILING(X)
向上取整(返回不小于 X 的最小整数)
sql
SELECT CEIL(3.2);
-- 4
3.FLOOR(X)
向下取整(返回不大于 X 的最大整数)
sql
SELECT FLOOR(3.9);
-- 3
4.ROUND(X,D)
四舍五入,保留 D 位小数。
sql
SELECT ROUND(3.14159,2);
-- 3.14
sql
SELECT ROUND(3.56);
-- 4
5.RAND()
返回 0~1 之间随机小数。
sql
SELECT RAND();
随机抽取一条数据
sql
SELECT * FROM student ORDER BY RAND() LIMIT 1;
六: 其他常用函数
1.VERSION( )
查看当前 MySQL 版本。
sql
SELECT VERSION();
2.DATABASE( )
查看当前正在使用的数据库。
sql
SELECT DATABASE();
3.USER( )
查看当前登录用户。
sql
SELECT USER();
4.MD5(str)
对字符串进行 MD5 摘要加密,返回 32 位字符串。
sql
SELECT MD5('123456');
常用于:
- 密码加密存储(旧项目常见)
- 数据校验
实际开发更推荐使用更安全的加密方式(如 bcrypt)。
5.IFNULL(val1,val2)
如果 val1 为 NULL,则返回 val2,否则返回 val1。
sql
SELECT IFNULL(NULL,'默认值');
-- 默认值
sql
SELECT IFNULL(100,0);
-- 100
实际开发常用场景
查询工资为空时显示 0
sql
SELECT name, IFNULL(salary,0) FROM emp;