1.函数
1-1.字符函数
length函数用于获取参数值的字节个数
select length('john');
结果:
4
concat函数拼接字符串
select concat(l_name,'_',f_name) 姓名 from emp;
upper、lower函数改变大小写
substr、substring函数截取,索引从1开始
-- 截取从指定索引处后面的所有字符
select substr('李莫愁爱上了陆展元',7);
-- 截取从指定索引处指定字符长度的字符
select substr('李莫愁爱上了陆展元',1,3);
结果:
陆展元
李莫愁
instr函数返回字符串第一次出现的索引,若找不到,则返回0
select instr('杨不悔爱上了殷六侠','殷六侠‘');
结果:
7
trim函数去前后空格
select trim('张翠山');
select trim('a' from 'aaa张aaaa翠山aaaa');-- 去掉a
结果:
张翠山
张翠山
lpad函数用指定字符实现左填充指定长度
select lpad('aaa','5','*');
结果:
**aaa
rpad函数同上
replace函数替换
select replace('aaabbbddd','ddd','ccc');
结果:
aaabbbccc
1-2.数学函数
round()函数四舍五入
ceil函数向上取整
floor函数向下取整
truncate函数截断
mod函数取余
1-3.日期函数
now函数
select now();
curdate函数返回当前日期,不包含时间
select curdate();
curtime函数返回当前时间,不包含日期
获取指定部分,年,月,日
select year(now()) as '年';
str_to_date函数
str_to_date('9-13-1999','%m-%d-%Y');
date_format函数
date_format('2018/6/6','%Y年%m月%d日');
1-4.其他函数
version()
database()
user()
2.排序(升序,降序)
按照工资升序,找出员工名和薪资?
select
ename,sal
from
emp
order by
sal;
PS:默认是升序。怎么指定升序或者降序呢?asc表示升序,desc表示降序。
order by子句应该在from子句后面,若是使用limit时,limit应该位于order by之后。
select ename , sal from emp order by sal; -- 升序
select ename , sal from emp order by sal asc; -- 升序
select ename , sal from emp order by sal desc; -- 降序
按照工资的降序排列,当工资相同的时候再按照名字的升序排列。
select ename,sal from emp order by sal desc , ename asc;
PS:越靠前的字段越能起到主导作用。只有当前面的字段无法完成排序的时候,才会启用后面的字段。
找出工作岗位是SALESMAN的员工,并且要求按照薪资的降序排列。
select
ename,job,sal
from
emp
where
job = 'SALESMAN'
order by
sal desc;
总结:
select
字段 3
from
表名 1
where
条件 2
order by
.... 4
-- order by是最后执行的。
3.分组函数
- count 计数
- sum 求和
- avg 平均值
- max 最大值
- min 最小值
记住:所有的分组函数都是对“某一组”数据进行操作的。
找出工资总和?
select sum(sal) from emp;
找出最高工资?
select max(sal) from emp;
找出总人数?
select count(*) from emp;
select count(ename) from emp;
count(*)和count(具体的某个字段),他们有什么区别?
- count(*):不是统计某个字段中数据的个数,而是统计总记录条数。(和某个字段无关)
- count(comm): 表示统计comm字段中不为NULL的数据总数量。
分组函数一共5个。
分组函数还有另一个名字:多行处理函数。
多行处理函数的特点:输入多行,最终输出的结果是1行。
分组函数也能组合起来用:
select count(*),sum(sal),avg(sal),max(sal),min(sal) from emp;
结果:
+———-+———-+————-+———-+———-+
| count(*) | sum(sal) | avg(sal) | max(sal) | min(sal) |
+———-+———-+————-+———-+———-+
| 14 | 29025.00 | 2073.214286 | 5000.00 | 800.00 |
+———-+———-+————-+———-+———-+
分组函数自动忽略NULL。
select count(comm) from emp;
结果:
+————-+
| count(comm) |
+————-+
| 4 |
+————-+
select sum(comm) from emp;
//select sum(comm) from emp where comm is not null; 不需要额外添加这个过滤条件。sum函数自动忽略NULL。
结果:
+———–+
| sum(comm) |
+———–+
| 2200.00 |
+———–+
找出工资高于平均工资的员工?
select ename,sal from emp where sal > avg(sal); //ERROR 1111 (HY000): Invalid use of group function
分析:
以上的错误信息:无效地使用了分组函数。
原因:SQL语句当中有一个语法规则,==分组函数不可直接使用在where子句当中。
why——>因为group by是在where执行之后才会执行的。
select 5
..
from 1
..
where 2
..
group by 3
..
having 4
..
order by 6
..
解决:
第一步:找出平均工资
select avg(sal) from emp;
+————-+
| avg(sal) |
+————-+
| 2073.214286 |
+————-+
第二步:找出高于平均工资的员工
select ename,sal from emp where sal > 2073.214286;
+——-+———+
| ename | sal |
+——-+———+
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
| FORD | 3000.00 |
+——-+———+
以上两步合为一步:
select ename,sal from emp where sal > (select avg(sal) from emp);
4.单行处理函数
什么是单行处理函数?输入一行,输出一行。
计算每个员工的年薪?
select ename,(sal+comm)*12 as yearsal from emp;
重点:所有数据库都是这样规定的,只要有NULL参与的运算结果一定是NULL。
使用ifnull函数:
select ename,(sal+ifnull(comm,0))*12 as yearsal from emp;
ifnull() 空处理函数?
- ifnull(可能为NULL的数据,被当做什么处理)
- 属于单行处理函数
select ename,ifnull(comm,0) as comm from emp;
+——–+———+
| ename | comm |
+——–+———+
| SMITH | 0.00 |
| ALLEN | 300.00 |
| WARD | 500.00 |
| JONES | 0.00 |
| MARTIN | 1400.00 |
| BLAKE | 0.00 |
| CLARK | 0.00 |
| SCOTT | 0.00 |
| KING | 0.00 |
| TURNER | 0.00 |
| ADAMS | 0.00 |
| JAMES | 0.00 |
| FORD | 0.00 |
| MILLER | 0.00 |
+——–+———+
5.group by和having
group by : 按照某个字段或者某些字段进行分组。
having : having是对分组之后的数据进行再次过滤。
案例:找出每个工作岗位的最高薪资。
select max(sal),job from emp group by job;
+———-+———–+
| max(sal) | job |
+———-+———–+
| 3000.00 | ANALYST |
| 1300.00 | CLERK |
| 2975.00 | MANAGER |
| 5000.00 | PRESIDENT |
| 1600.00 | SALESMAN |
+———-+———–+
注意:分组函数一般都会和group by联合使用,这也是为什么它被称为分组函数的原因。
并且任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的。
当一条SQL语句没有group by的话,整张表的数据会自成一组。
select ename,max(sal),job from emp group by job;
以上在mysql当中,查询结果是有的,但是结果没有意义,在Oracle数据库当中会报错。语法错误。
Oracle的语法规则比MySQL语法规则严谨。
记住一个规则:当一条语句中有group by的话,select后面只能跟分组函数和参与分组的字段。
每个工作岗位的平均薪资?
select job,avg(sal) from emp group by job;
+———–+————-+
| job | avg(sal) |
+———–+————-+
| ANALYST | 3000.000000 |
| CLERK | 1037.500000 |
| MANAGER | 2758.333333 |
| PRESIDENT | 5000.000000 |
| SALESMAN | 1400.000000 |
+———–+————-+
多个字段能不能联合起来一块分组?
案例:找出每个部门不同工作岗位的最高薪资。
select
deptno,job,max(sal)
from
emp
group by
deptno,job;
找出每个部门的最高薪资,要求显示薪资大于2900的数据。
第一步:找出每个部门的最高薪资
select max(sal),deptno from emp group by deptno;
+———-+——–+
| max(sal) | deptno |
+———-+——–+
| 5000.00 | 10 |
| 3000.00 | 20 |
| 2850.00 | 30 |
+———-+——–+
第二步:找出薪资大于2900
select max(sal),deptno from emp group by deptno having max(sal) > 2900; -- 这种方式效率低。
select max(sal),deptno from emp where sal > 2900 group by deptno; -- 效率较高,建议能够使用where过滤的尽量使用where。
找出每个部门的平均薪资,要求显示薪资大于2000的数据。
第一步:找出每个部门的平均薪资
select deptno,avg(sal) from emp group by deptno;
+——–+————-+
| deptno | avg(sal) |
+——–+————-+
| 10 | 2916.666667 |
| 20 | 2175.000000 |
| 30 | 1566.666667 |
+——–+————-+
第二步:要求显示薪资大于2000的数据
select deptno,avg(sal) from emp group by deptno having avg(sal) > 2000;
where后面不能使用分组函数:
select deptno,avg(sal) from emp where avg(sal) > 2000 group by deptno; -- 错误了。
这种情况只能使用having过滤。
6.总结
select 5
..
from 1
..
where 2
..
group by 3
..
having 4
..
order by 6
..