oracle 基础练习题2(scott用户下的emp,dept表)

前言:此文主要为了记录学习,分享,希望爱学习之人能有所收获。

1.查询工资在0-1000,1000-2000,2000-3000,3000以上各个工资范围的员工数。
2.要求查询出: 部门名称,部门的员工数,部门的平均工资,部门的最低收入雇员的姓名
3.原题有错误,思考题,删除emp表中重复的记录
个人思路:用原表minus去重的表则得到重复的记录,然后删除即可。但是emp表中有唯一主键,所以不存在重复的数据。
4.求出每个部门的最低工资的雇员的信息(两种方法)
5.查询各个职位员工工资大于平均工资(平均工资包括所有员工)的人数和员工职位(两种方法)
6.写出一个部门至少有四个员工的记录
7.列出所有员工的姓名及其直接上级的姓名
8.返回比本部门平均工资高的员工的empno,ename,deptno,sal,以及平均工资
9.查询与7369或者7499号具有相同job和deptno的其他员工的empno,ename,job和deptno
10.列出从事同一种工作但属于不同部门的雇员的不同组合
11.查询员工工资2到5名的员工信息
12.列出薪金比SMITH多的所有员工信息
13.把hiredate列看做是员工的生日,求本月过生日的员工(两种方法)
14.查询出1981年各个月入职的员工数
15.将系统时间转化成年月日的形式

1、select sum(case when sal>0 and sal<=1000 then 1 else 0 end) “0 sum(case when sal>1000 and sal<=2000 then 1 else 0 end) as “1000 sum(case when sal>2000 and sal<=3000 then 1 else 0 end) as “2000 sum(case when sal>3000 then 1 else 0 end) as “sal>3000” FROM EMP;

2、select dname,count(dname),round(avg(sal),1),min(sal) from (select * from emp e join dept d on e.deptno=d.deptno) group by dname;

select dname,count(dname),round(avg(sal),1),min(sal) from emp e, dept d where e.deptno=d.deptno group by dname;

4、
1.select * from emp where sal in(select min(sal) from emp group by deptno);

2.select * from emp where sal in(select sal from (select sal,row_number()over(partition by deptno order by sal asc) rn from emp) where rn<2);

3.select * from emp where sal =any(select min(sal) from emp group by deptno);
学会了一样新的技能,in可以用= any代替;

5、
1.select job,count(1) from emp where sal>(select avg(sal) from emp) group by job;

2.select job,sum(case when sal>(select avg(sal) from emp) then 1 else 0 end) from emp group by job;

3.select job,sum(decode(sign(sal-(select avg(sal) from emp)),1,1,0,0,-1,0))from emp group by job;

引申:select empno,decode(empno,7369,‘小smith’,7499,‘小allen’,7521
,‘小ward’,7566,‘小jones’,‘不详’) where rownum<=6;
这句执行会发现能查到前六行的记录,且按照我们的要求更改了,可以说这是一种简易的case when,但是不知道假如empno存在相同值时会如何

6、select * from emp where deptno=any(select deptno from emp group by deptno having count(deptno)>3);

7、select a.ename 员工,b.ename 员工上级 from emp a left join emp b on a.mgr=b.empno;

8、select empno,ename,e.deptno,sal,round(av,0) 取整的平均工资 from emp e join (select deptno,avg(sal) av from emp group by deptno) a on e.deptno=a.deptno where e.sal>a.av;

9、select empno,ename,a.job,a.deptno from emp a,(select job,deptno from emp where empno in(‘7369’,‘7499’)) b where a.deptno=b.deptno and a.job=b.job and a.empno !=‘7369’ and a.empno!=‘7499’;

原楼主错误(未注意“其他”两个字):select empno,ename,job,deptno from emp where (job,deptno) in(select job,deptno from emp where empno in(7369,7499));
但是where条件后的这种两字段和在一块的写法之前并未见过,学习了。

10、select a.job,a.deptno,b.job job1,b.deptno deptno1 from emp a,emp b where a.job=b.job and a.deptno!=b.deptno;
这个查询结果并不完美,因为存在重复的数据,包括完全相同还有组合交换位置的重复。

11、select b.* from (select a.*,rownum rn from (select * from emp order by sal desc) a) b where b.rn>1 and b.rn<6;

12、select * from emp where sal>(select sal from emp where ename=‘SMITH’);

13、
1.select * from emp where substr(to_char(hiredate,‘yyyy-MM-dd’),6,2)=substr(to_char(sysdate,‘YYYY-MM-DD’),6,2);

2.select * from emp where EXTRACT(month FROM hiredate)=EXTRACT(month from sysdate)

3.select * from emp where to_char(hiredate,‘MM’)=to_char(sysdate,‘MM’);
这三种方式都可以,后两种比较简便,还有一个问题,为什么to_char(sysdate,0,2)和to_char(sysdate,1,2)两者结果是一样的???理论上应该是零开始,什么原因呢?

14、select to_char(hiredate,‘yyyy-MM’),count(1) from emp group by to_char(hiredate,‘yyyy-MM’) having substr(to_char(hiredate,‘yyyy-MM’),1,4)=‘1981’;

select to_char(hiredate,‘yyyy-MM’),count(1) from emp where to_char(hiredate,‘yyyy’)=‘1981’ group by to_char(hiredate,‘yyyy-MM’);

select * from (select to_char(hiredate,‘yyyy-MM’) 入职时间,count(1) from emp group by to_char(hiredate,‘yyyy-MM’)) a where substr(a.入职时间,1,4)=‘1981’;
还是要注意什么时候能用别名,有的函数会将别名降级,这个时候别名就会无法识别,因此也就无效了,只能在前面再加一层select。

15、复杂版:select to_char(sysdate,‘yyyy’)||‘年’||ltrim(to_char(sysdate,‘mm’),‘0’)||‘月’||to_char(sysdate,‘dd’)||‘日’
from dual;

简洁版:select to_char(sysdate,‘fmyyyy"年"mm"月"dd"日"’) from dual;

双引号可以将任何字符串插进去:select to_char(sysdate,’"yyyy=“yyyy” mm=“mm” dd="dd’) from dual;

FM可以不区分大小写,裁掉日和月前面的0:
select to_char(date’2018-02-01’,‘yyyy,mm,dd’) from dual;(结果:2018,02,01)
select to_char(date’2018-02-01’,‘fmyyyy,mm,dd’) from dual;(结果:2018,2,1)

注意分钟是mi,不同于Java中的mm
select to_char(sysdate,‘yyyyMMdd hh:mi:ss’) from dual;(结果:20181212 10:46:25)

当前时间减去3天的时间
select sysdate-interval’3’hour from dual;

你可能感兴趣的:(基础,oracle)