1.单行处理机
1.1 什么是单行处理机?
- 输入一行,输出一行。
1.2计算每个员工的年薪
select ename,(sal+comm) * 12 as yearsal from emp; // 错误写法
使用ifnull函数处理:
select ename,(sal + ifnull(comm,0)) * 12 as yearsal from emp; // 正确写法
重点: 所有数据库都是这样规定的,只要有NULL参与的运算结果一定是NULL。
1.3 ifnull() 空处理函数?
语法格式:
ifnull(可能为NULL的数据,被当做什么处理) : 属于单行处理函数。
1.4 将津贴中的 NULL 转换为 0
select ename,ifnull(comm,0) as comm from emp;
2.分组查询 group by 和 having
- group by : 按照某个字段或者某些字段进行分组。
- having : 是对分组之后的字段再次过滤。
2.1找出每个岗位的最高薪资
select max(sal) from emp group by job;
注意:
- 分组函数一般都会和group by 联合使用。这也是为什么被称为分组函数的原因。
- 并且任何一个分组函数(count,sum,max,min,avg)都是在group by语句执行结束之后才会执行的。
- 当一条 sql 语句没有group by的话,整张表的数据会自成一组。
2.2多字段分组查询
select ename,max(sal),job from emp group by job;
// 以上在 mysql当中,查询结果是有的,但是结果没有意义,在Oracle数据库当中会报错,语法错误。
重点: 记住一个规则,当一条语句中有 group by 的话,select后面只能跟分组函数和参与分组的字段。
2.3每个工作岗位的平均工资
select obj,avg(sal) from emp group by job;
2.4多个字段联合起来一块分组,找出每个部门不同工作岗位的最高薪资。
select deptno,job,max(sal) from emp group by deptno,job;
2.5 找出每个部门的最高薪资,要求显示薪资大于2900的数据
第一步: 找出每个部门的最高薪资
select deptno,max(sal) from emp group by deptno;
第二步: 找出薪资大于2900 这种方式效率低
select deptno,max(sal) from emp group by deptno having max(sal) > 2900;
完美方案:效率较高,要求显示薪资大于2900的数据。
select deptno,max(sal) from emp where sal > 2900 group by deptno;
2.6 找出每个部门的平均薪资
第一步 : 找出每个部门的平均薪资
select deptno,avg(sal) from emp group by deptno;
第二步 : 要求显示薪资大于2000的数据
select deptno,avg(sal) from emp group by deptno having avg(sal) > 2000;
// 错误,where后边不能使用分组函数,这种情况只能使用 having 过滤
select deptno,avg(sal) from emp where avg(sal) > 2000 group by deptno; // 错误
3.总结一个完整的 DQL 语句怎么写
select ... from ... where ... group by ... having ... order by ... 复制代码
4.连接查询
4.1 关于查询结果的去重 (关键字 distinct ,去除重复记录)
select distinct job from emp;
4.2 以下语句是错误的
select ename,distinct job from emp;
重点: distinct只能出现在所有字段的最前面。
4.3 多个字段联合去重
select distinct deptno,job from emp;
4.4 统计岗位数量
select count(distinct job) from emp;
5.链接查询的概念
- 在实际的开发中,大部分的情况下都不是从单表中查询数据,一般都是多张表联合查询取出最终的结果。
- 在实际的开发中,一般一个业务都会对应多张表,比如 :学生和班级,起码两张表。
如果学生和班级信息存储到一张表中,结果就像上面一样,数据会存在大量的重复,导致数据的沉余。
5.1连接查询的分类
5.1.1 根据语法出现的年代划分的话,包括:
- SQL92 (一些老的DBA可能还在使用这种语法。DBA : DataBase Administrator,数据库管理员)
- SQL99 (比较新的语法)
5.1.2 根据表的连接方式来划分,包括:
- 内连接 :
- 等值连接
- 非等值连接
- 自连接
- 外连接 :
- 左外连接 (左连接)
- 右外连接 (右连接)
- 全连接 (这个不经常使用!!)
5.1.3连接查询有一种现象: 笛卡尔积现象。
5.2案例:找出每一个员工的部门名称,要求显示员工名和部门名。
select ename.deptno from emp;
EMP 表:
select deptno,dname from dept;
DEPT 表 :
ename 和 dname要联合在一块显示,粘到一块。
select ename,dname from emp,dept;
其中一共有 14 * 4 行数据,一个名字对应四个部门名称
原理 : 两张表通过 deptno 进行查询连接
笛卡尔积现象 : 当两张表进行连接查询的时候,没有任何条件的限制,最终的查询结果条数是两张表记录条数的乘积。
6.关于表的别名 :
select e.ename,d.dname from emp e,dept d; (此处省略了 as )
6.1 表的别名有什么好处:
- 执行效率高
- 可读性好
- 怎么避免笛卡尔积现象?当然是加入条件进行过滤
- 避免了笛卡尔积现象,会减少记录的匹配次数嘛? 1.不会,次数还是 56 次,只不过显示的都是有效记录。
6.2找出每一个员工的部门名称,要求显示员工名和部门名。
这个是SQL92,以后不用 select e.ename,dname from emp e,dept d where e.deptno = d.deptno