select*from emp orderby comm; select*from emp orderby comm desc;--空值在排序时大于最大值
注意点:
1.order by 后面除了跟正常的字段名外,还可以跟别名 –因为 order by 执行顺序在 select 之后,所以order by 可以认识别名
1
select job 职位 from emp orderby 职位;
2.可以用数字指代字段–数字几就是第几个字段
1 2 3
select ename,job,sal,deptno from emp order by 1; select ename,job,sal,deptno from emp order by 2; select ename,job,sal,deptno from emp order by 2,3 desc;
3.order by 后面可以跟运算、函数、case when,而且在 order by 后面的内容只参与排序,不显示
1 2 3 4 5
select*from emp orderby nvl(comm,1000); select*from emp orderbycasewhen deptno =10then2 when deptno =20then1 when deptno =30then3 endasc;
1.查询各部门最高薪资和最低薪资的差值,输出部门编号跟差值 select deptno,max(sal) -min(sal) from emp groupby deptno;
2.查询薪资在1000~3000之间,按照有佣金和无佣金分组,输出薪资合计和平均薪资。 --难点:select执行顺序在分组之后,所以分组无法直接使用select里的case when selectcasewhen comm isnotnullthen'有佣金'when comm isnullthen'无佣金'end 佣金,sum(sal),avg(sal) from emp where sal between1000and3000 groupbycasewhen comm isnotnullthen'有佣金'when comm isnullthen'无佣金'end;
selectsum(sal),avg(sal) from emp where sal between1000and3000 groupbycasewhen comm isnotnullthen'有佣金'when comm isnullthen'无佣金'end;
3.查询1982年以前入职的员工,按照'CLERK' 跟 '不是CLERK' 分组,查询岗位类型,平均薪资,最高薪资,按照最高薪资降序排序 --分组后面跟排序 selectcasewhen job ='CLERK'then'办事员'else'不是办事员'end 岗位类型,avg(sal),max(sal) from emp where hiredate < to_date('1982-01-01','yyyy-mm-dd') groupbycasewhen job ='CLERK'then'办事员'else'不是办事员'end orderby3desc;
4.查询职位为经理,最低薪资大于2000的员工的 部门编号,总薪资 并按照部门编号进行分组,最后按照总薪资降序排序 select deptno,sum(sal) from emp where job ='MANAGER'andmin(sal) >2000 groupby deptno orderby2desc;
having–专门针对分组函数的比较 –只能跟在group by后面 –having 中有的字段,group by 中必须有
1 2 3 4 5 6 7 8
select deptno, sum(sal) from emp where job = 'MANAGER' group by deptno having min(sal) > 2000 order by 2 desc;
select deptno,sum(sal) from emp where job = 'MANAGER' group by deptno having min(sal) > 2000 order by 2 desc;
特点: 1.子查询必定被括号包裹,跟父查询之间用逻辑运算符或exists连接(> < = != in any all exists) 2.子查询可以有多层 3.子查询可以添加在以下几个位置 select 子查询–把子查询结果作为字段使用 from 子查询–把子查询结果作为表使用 where 子查询–把子查询结果作为条件使用 having 子查询–把子查询结果作为条件使用 select 字段/子查询 from 表/子查询 where 条件/子查询 group by 字段 having 条件/子查询 order by 字段;
1.查询SMITH所在部门的所有员工信息 select DEPTNO from emp where ename ='SMITH'; select*from emp where deptno =20;
select*from emp where deptno in(select DEPTNO from emp where ename ='SMITH');--子查询与父查询条件要一一对应
2.查询scott手下有哪些员工 select empno from emp where ename ='SCOTT'; select*from emp where mgr in(select empno from emp where ename ='SCOTT');--子查询与父查询字段名可以不同
3.查询公司工资最高的那个人的全部信息 selectmax(sal) from emp; select ename from emp where sal = (selectmax(sal) from emp); select*from emp where ename = (select ename from emp where sal = (selectmax(sal) from emp));--嵌套查询可以有多层
select*from emp where sal = (selectmax(sal) from emp);
4-1.查询与'smith'和'scott'同部门的员工信息 select*from emp where deptno in(select deptno from emp where ename in('KING','SCOTT')); select*from emp forupdate;
4-2.查询与'YIFAN'和'scott'同部门且同薪资的员工信息 (要的结果为:10800 或者 203000) select*from emp where deptno in(select deptno from emp where ename in('YIFAN','SCOTT')) and sal in(select sal from emp where ename in('YIFAN','SCOTT'));--错误,得出的结果多出预期
select*from emp where (deptno,sal) in(select deptno,sal from emp where ename in('YIFAN','SCOTT'));
1.查询与'smith'和'scott'同岗位 或 同薪资的员工信息 select*from emp where JOB in(select JOB from emp where ename in('SMITH','SCOTT')) and sal in(select sal from emp where ename in('SMITH','SCOTT'));
select*from emp where JOB in(select JOB from emp where ename in('SMITH','SCOTT')) or sal in(select sal from emp where ename in('SMITH','SCOTT'));
2.查询与'smith'和'scott'同岗位 且 同薪资的员工信息 SELECT*FROM EMP WHERE (JOB,SAL) IN (SELECT JOB,SAL FROM EMP WHERE ENAME IN('SMITH','SCOTT'));
二. having 子查询
–主要解决分组函数比较问题,或分组后附加条件
注意:聚合函数的嵌套不能写在having后 –可以写在select后
1 2 3 4 5
输出薪资大于员工平均薪资 的所有信息 select*from emp where sal > (selectavg(sal) from emp);
输出部门平均薪资大于员工平均薪资 的部门编号与平均薪资 select deptno,avg(sal) from emp groupby deptno havingavg(sal) > (selectavg(sal) from emp);
三. from 子查询
–把子查询结果作为表来使用(把一张表内的部分内容当作一张表使用),常见于解决表连接问题
1 2 3 4 5 6 7 8 9
select*from (select'稍嫌钱','邵乾坤','蒋廷禹'from emp where deptno =20);
求史密斯所在部门工资最高的员工信息 select deptno from emp where ename ='SMITH';
selectmax(sal) from emp where deptno = (select deptno from emp where ename ='SMITH');
select*from (select*from emp where deptno = (select deptno from emp where ename ='SMITH')) where sal in (selectmax(sal) from emp where deptno = (select deptno from emp where ename ='SMITH'));
四. select 子查询
–子查询只能返还一个值
1 2 3 4 5 6 7
select (selectmax(sal) from emp) - sal from emp; select (selectmax(sal) from emp) - (selectavg(sal) from emp),sal from emp;
select (select sal from emp) from emp;--错误,子查询返回了一组值
输出10号部门跟20号部门平均薪资的差 select (selectavg(sal) from emp where deptno =10)-(selectavg(sal) from emp where deptno =20) from emp;
--按照关联条件进行关联,将两张表中符合关联条件的内容全部输出 select 字段 from 表A innerjoin 表B on 两个表共有的字段;
select ename,loc from emp a innerjoin dept b on a.deptno = b.deptno; select*from (emp a join dept b on a.deptno = b.deptno);
select deptno,sal,ename,dname from emp a join dept b on a.deptno = b.deptno;--报错,未明确定义列 select a.deptno,sal,ename,dname from emp a join dept b on a.deptno = b.deptno; select b.deptno,sal,ename,dname from emp a join dept b on a.deptno = b.deptno; --因为deptno列是两张表都有的列,在使用时必须声明使用哪张表中的列
二. 外连接
(左外连接,右外连接,全外连接)
按照关联条件进行关联,将两张表中符合关联条件的内容全部输出,不符合关联条件的部分根据情况输出
1.左外连接
left join
1 2 3 4
--按照关联条件进行关联,以左表数据为主(左表内容全部输出,右边没用对应关系的部分用null填充) select 字段 from 表A leftjoin 表B on 两个表共有的字段;
select*from DEPT a leftjoin EMP b on a.deptno = b.deptno;
2.右外连接
right join
1 2 3 4
--按照关联条件进行关联,以右表数据为主(右表内容全部输出,左边没用对应关系的部分用null填充) select 字段 from 表A rightjoin 表B on 两个表共有的字段;
select*from emp a rightjoin dept b on a.deptno = b.deptno;
3.全外连接
full join
1 2 3 4
--按照关联条件进行关联,所有数据全部输出(没有对应关系的部分用null填充) select 字段 from 表A fulljoin 表B on 两个表共有的字段;
select*from emp a fulljoin dept b on a.deptno = b.deptno;
三. 笛卡尔积
cross join
容易造成死机,只有两张表中数据都不多的时候可以使用
1 2 3 4
--交叉连接,不需要关联条件,把两张表中所有的行进行交叉输出 select 字段 from 表A crossjoin 表B;
select*from emp a crossjoin dept b;
特殊的连接方式
–需要关联条件的名称跟数据类型均相同
一. 自然连接 natural
结果等同于内连接
1 2 3 4 5
--不需要写关联条件,自然连接会自动查找两个表中同名字段进行关联(有几个同名字段关联几个) --被关联的字段会出现在表的最前面,并且只出现一次 select 字段 from 表A naturaljoin 表B;