目录
1.聚合函数
1.1 count
1.2 sum
1.3 avg
1.4 max 和 min
2. group by
2.1 group by 的条件筛选——having
2.2 总结
3.日期函数
4.字符串函数
concat
replace
substring
以首字母大写,其余字母小写的方式显示员工的姓名
5.数学函数
format
rand()
6.其他函数
user()
md5
1.聚合函数
函数 | 说明 |
count( [DISTINCT] 参数 ) | 返回查询到的数据的数量 |
sum ( [DISTINCT] 参数) | 返回查询到的数据的总和,不是数字没有意义 |
avg ( [DISTINCT] 参数 ) | 返回查询到的数据的平均值,不是数字没有意义 |
max ( [DISTINCT] 参数) | 返回查询到的数据的最大值,不是数字没有意义 |
min ( [DISTINCT] 参数) | 返回查询到的数据的最小值,不是数字没有意义 |
什么是聚合函数?
聚合统计一定是直接或者间接统计列方向的某些数据。列方向上一定是相同属性的。对于行方向上,可以直接使用select 表达式相加/相乘等进行统计。
1.1 count
当想查看,当前筛选出来的结果有几条时,可以使用count函数
使用 * 做统计,NULL不纳入统计。也可以用 count(1)等表达式进行统计
mysql> select count(*) from exam_result;
+----------+
| count(*) |
+----------+
| 7 |
+----------+
mysql> select count(name) from exam_result;
+-------------+
| count(name) |
+-------------+
| 7 |
+-------------+
1 row in set (0.00 sec)
查看去重之后的统计个数
mysql> select count(distinct math) from exam_result;
+----------------------+
| count(distinct math) |
+----------------------+
| 6 |
+----------------------+
1 row in set (0.00 sec)
mysql> select count(math) from exam_result;
+-------------+
| count(math) |
+-------------+
| 7 |
+-------------+
1.2 sum
统计英语成绩总分
mysql> select sum(english) from exam_result;
+--------------+
| sum(english) |
+--------------+
| 443 |
+--------------+
1 row in set (0.00 sec)
mysql> select sum(english) from exam_result where english<60;
+--------------+
| sum(english) |
+--------------+
| 131 |
+--------------+
1.3 avg
计算英语成绩的平均分
mysql> select sum(english)/count(*) from exam_result ;
+-----------------------+
| sum(english)/count(*) |
+-----------------------+
| 63.285714285714285 |
+-----------------------+
1 row in set (0.00 sec)
mysql> select avg(english) from exam_result;
+--------------------+
| avg(english) |
+--------------------+
| 63.285714285714285 |
+--------------------+
1 row in set (0.00 sec)
计算总分的平均分
mysql> select avg(english+math+chinese) from exam_result;
+---------------------------+
| avg(english+math+chinese) |
+---------------------------+
| 222 |
+---------------------------+
1.4 max 和 min
返回英语最高分
mysql> select max(english) from exam_result;
+--------------+
| max(english) |
+--------------+
| 90 |
+--------------+
1 row in set (0.00 sec)
返回 > 70 分以上的数学最低分
mysql> select min(math) from exam_result where math>70;
+-----------+
| min(math) |
+-----------+
| 73 |
+-----------+
1 row in set (0.00 sec)
2. group by
在select中使用group by 子句可以对指定列进行分组查询。
表结构如下
显示每个部门的平均工资和最高工资
mysql> select deptno,avg(sal) avgsal,max(sal) maxasl from emp group by deptno;
+--------+-------------+---------+
| deptno | avgsal | maxasl |
+--------+-------------+---------+
| 10 | 2916.666667 | 5000.00 |
| 20 | 2175.000000 | 3000.00 |
| 30 | 1566.666667 | 2850.00 |
+--------+-------------+---------+
3 rows in set (0.00 sec)
显示每个部门的每种岗位的平均工资和最低工资
mysql> select deptno,job,avg(sal) avgsal,max(sal) maxasl from emp group by deptno,job;
+--------+-----------+-------------+---------+
| deptno | job | avgsal | maxasl |
+--------+-----------+-------------+---------+
| 10 | CLERK | 1300.000000 | 1300.00 |
| 10 | MANAGER | 2450.000000 | 2450.00 |
| 10 | PRESIDENT | 5000.000000 | 5000.00 |
| 20 | ANALYST | 3000.000000 | 3000.00 |
| 20 | CLERK | 950.000000 | 1100.00 |
| 20 | MANAGER | 2975.000000 | 2975.00 |
| 30 | CLERK | 950.000000 | 950.00 |
| 30 | MANAGER | 2850.000000 | 2850.00 |
| 30 | SALESMAN | 1400.000000 | 1600.00 |
+--------+-----------+-------------+---------+
9 rows in set (0.00 sec)
2.1 group by 的条件筛选——having
having和group by配合使用,对group by结果进行过滤
mysql> select deptno,avg(sal) avgsal from emp group by deptno;
+--------+-------------+
| deptno | avgsal |
+--------+-------------+
| 10 | 2916.666667 |
| 20 | 2175.000000 |
| 30 | 1566.666667 |
+--------+-------------+
3 rows in set (0.00 sec)
mysql> select deptno,avg(sal) avgsal from emp group by deptno having avgsal<2000;
+--------+-------------+
| deptno | avgsal |
+--------+-------------+
| 30 | 1566.666667 |
+--------+-------------+
1 row in set (0.00 sec)
2.2 总结
- group by将数据分开了,可以对特定组内进行某种操作。group by一定是配合聚合统计使用的。
- group by后面跟的是分组的依据,只有这些依据可以出现在select 后面跟的参数中。
- where和having并不冲突,where是在哪些条件下筛选出数据,而having是整个数据已经被全部筛选之后,挑选having条件满足的数据进行显示。
- where是在表中数据初步被筛选的时候起效果的,而having是在完成整个分组聚合统计,然后进行筛选的
3.日期函数
- 常用的日期函数
current_date() | 当前日期 |
current_time() | 当前时间 |
current_timestamp() | 当前时间戳 |
date(datetime) | 返回datetime参数的日期部分 |
date_add(date, interval value) | 在date中添加日期或者时间 单位可以是year minute second day |
date_sub(date, interval value) | 在date中减去日期或者时间 单位和date_add相同 |
datediff(date1,date2) | 两个日期的差,注意是前减后 单位是填 |
now() | 当前时间 |
- 获得当前时间/日期/时间戳
mysql> select current_date();
+----------------+
| current_date() |
+----------------+
| 2023-05-04 |
+----------------+
1 row in set (0.00 sec)
mysql> select current_time();
+----------------+
| current_time() |
+----------------+
| 20:37:49 |
+----------------+
1 row in set (0.00 sec)
mysql> select current_timestamp();
+---------------------+
| current_timestamp() |
+---------------------+
| 2023-05-04 20:37:55 |
+---------------------+
1 row in set (0.00 sec)
- 日期之间的加减和距离
日期函数之中可以嵌套日期函数,比如需要输入当前日期时可以嵌套使用now()函数
datediff(date1,date2) 是用date1减去date2 ,如果小于则会显示负数。
mysql> select date_add('2023-05-04',interval 5 day);
+---------------------------------------+
| date_add('2023-05-04',interval 5 day) |
+---------------------------------------+
| 2023-05-09 |
+---------------------------------------+
mysql> select date_add(now(),interval 5 day);
+--------------------------------+
| date_add(now(),interval 5 day) |
+--------------------------------+
| 2023-05-09 20:40:53 |
+--------------------------------+
mysql> select date_sub('2023-05-09',interval 5 day);
+---------------------------------------+
| date_sub('2023-05-09',interval 5 day) |
+---------------------------------------+
| 2023-05-04 |
+---------------------------------------+
mysql> select datediff('2023-05-04','2022-05-04');
+-------------------------------------+
| datediff('2023-05-04','2022-05-04') |
+-------------------------------------+
| 365 |
+-------------------------------------+
1 row in set (0.00 sec)
mysql> select datediff('2022-05-04','2023-05-04');
+-------------------------------------+
| datediff('2022-05-04','2023-05-04') |
+-------------------------------------+
| -365 |
+-------------------------------------+
1 row in set (0.00 sec)
- 查询在两分钟内发布的留言
mysql> select * from 表名 where date_add(时间对应名称, interval 2 minute) > now();
4.字符串函数
charset(str) | 返回字符串字符集 |
concat(str1,str2,..) | 连接str1,str2...成为一个 |
instr(string,str) | 返回str在string中出现的位置 没有返回0 |
ucase(str) | 转换成大写 |
lcase(str) | 转换成小写 |
left(str,length) | 从str的左边截取length个字符 |
length(str) | str的长度 |
replace(str,search_str,replace_str) | 在str中用replace_str 替换search_str |
strcmp(str1,str2) | 逐字符比较两字符串的大小 |
substring(str,pos,[length] ) | 从str的pos位置截取length个字符 |
ltrim(string) rtrim(string) trim(string) | 去除左边的空格 去除右边的空格 去除左和右的空格 |
接下来是函数的具体使用
concat
mysql> select concat (' 姓名:',ename,' 工作:',job) from emp;
+----------------------------------------------+
| concat (' 姓名:',ename,' 工作:',job) |
+----------------------------------------------+
| 姓名:SMITH 工作:CLERK |
| 姓名:ALLEN 工作:SALESMAN |
| 姓名:WARD 工作:SALESMAN |
| 姓名:JONES 工作:MANAGER |
| 姓名:MARTIN 工作:SALESMAN |
| 姓名:BLAKE 工作:MANAGER |
| 姓名:CLARK 工作:MANAGER |
| 姓名:SCOTT 工作:ANALYST |
| 姓名:KING 工作:PRESIDENT |
| 姓名:TURNER 工作:SALESMAN |
| 姓名:ADAMS 工作:CLERK |
| 姓名:JAMES 工作:CLERK |
| 姓名:FORD 工作:ANALYST |
| 姓名:MILLER 工作:CLERK |
+----------------------------------------------+
replace
注意replace只是修改了显示时的数据,并没有修改表内的数据。
mysql> select replace (job,'A','B') from emp;
+-----------------------+
| replace (job,'A','B') |
+-----------------------+
| CLERK |
| SBLESMBN |
| SBLESMBN |
| MBNBGER |
| SBLESMBN |
| MBNBGER |
| MBNBGER |
| BNBLYST |
| PRESIDENT |
| SBLESMBN |
| CLERK |
| CLERK |
| BNBLYST |
| CLERK |
+-----------------------+
substring
mysql> select substring(ename,2),ename from emp;
+--------------------+--------+
| substring(ename,2) | ename |
+--------------------+--------+
| MITH | SMITH |
| LLEN | ALLEN |
| ARD | WARD |
| ONES | JONES |
| ARTIN | MARTIN |
| LAKE | BLAKE |
| LARK | CLARK |
| COTT | SCOTT |
| ING | KING |
| URNER | TURNER |
| DAMS | ADAMS |
| AMES | JAMES |
| ORD | FORD |
| ILLER | MILLER |
+--------------------+--------+
14 rows in set (0.00 sec)
mysql> select substring(ename,2,2),ename from emp;
+----------------------+--------+
| substring(ename,2,2) | ename |
+----------------------+--------+
| MI | SMITH |
| LL | ALLEN |
| AR | WARD |
| ON | JONES |
| AR | MARTIN |
| LA | BLAKE |
| LA | CLARK |
| CO | SCOTT |
| IN | KING |
| UR | TURNER |
| DA | ADAMS |
| AM | JAMES |
| OR | FORD |
| IL | MILLER |
+----------------------+--------+
以首字母大写,其余字母小写的方式显示员工的姓名
mysql> select concat(ucase(substring(ename,1,1)),lcase(substring(ename,2))) as name from emp;
mysql> select concat(ucase(substring(ename,1,1)),lcase(substring(ename,2))) as name from emp;
+--------+
| name |
+--------+
| Smith |
| Allen |
| Ward |
| Jones |
| Martin |
| Blake |
| Clark |
| Scott |
| King |
| Turner |
| Adams |
| James |
| Ford |
| Miller |
+--------+
5.数学函数
abs(number) | 绝对值函数 |
bin(number) | 十进制转二进制 |
hex(number) | 十进制转16进制 |
conv(number,from_base,to_base) | 进制转换 |
ceiling(number) | 向上取整 |
floor(number) | 向下取整 |
format(number,length) | number保留length位小数 四舍五入 |
rand() | 返回一个浮点数 取值范围为[0.0,1.0) |
mod(number,m) | number%m |
format
mysql> select format(12.345678,2);
+---------------------+
| format(12.345678,2) |
+---------------------+
| 12.35 |
+---------------------+
mysql> select format(12.345678,6);
+---------------------+
| format(12.345678,6) |
+---------------------+
| 12.345678 |
+---------------------+
rand()
mysql> select rand();
+---------------------+
| rand() |
+---------------------+
| 0.15591199058658628 |
+---------------------+
1 row in set (0.01 sec)
mysql> select rand();
+--------------------+
| rand() |
+--------------------+
| 0.1622132008543361 |
mysql> select format(rand(),2);
+------------------+
| format(rand(),2) |
+------------------+
| 0.34 |
+------------------+
mysql> select format(rand(),3);
+------------------+
| format(rand(),3) |
+------------------+
| 0.120 |
+------------------+
6.其他函数
user() | 查询当前用户 |
md5(str) | 对一个字符串进行摘要,摘要后得到 一个32位的字符串 |
database() | 显示当前正在使用的数据库 |
password() | mysql使用该函数对用户加密 |
ifnull(val1,val2) | 相当于三目操作符 如果val1是null 返回val2 如果val1不是null 返回val1 |
user()
在mysql中可以设置用户,用户会存放在user表中,对用户的管理,本质上就是对user表的增删查改。
md5
在某些表中我们需要存入用户的密码等私人信息,如果不对这些信息做处理,那么任意一个可以访问数据库的人都可以拿走这些信息,不安全。
name ->varchar(20) password->char(64)
mysql> insert into my_user (name,password) values('张三',md5('123456'));
这样在 select * from my_user表时,出现的就不是123456而是32位的字符串。
所以当我们查表的时候也需要使用md5
mysql> select * from my_user where md5('123456')=password;