正在玩命加载中 . . .

MySQL(二)


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
    ..

文章作者: LogicVan
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 LogicVan !
评论
  目录