Oracle的练习与优化
1.查询工资大于1200的员工姓名和工资
select ename,sal from emp where sal>1200;
2.查询员工号为7900的员工的姓名和部门号
select ename,deptno from emp where empno=7900;
3.选择工资不在2000到3000的员工的姓名和工资
select ename,sal from emp where sal not between 2000 and 3000;
4.选择雇用时间在1981-02-01到1982-05-01之间的员工姓名,job
和雇用时间
select ename,job,hiredate from emp
where hiredate between to_date('1981-02-01','yyyy-MM-dd') and to_date('1982-05-01','yyyy-MM-dd');
5.选择在20或40号部门工作的员工姓名和部门号
select ename,deptno from emp where deptno in(20,40);
6.选择在1981年雇用的员工的姓名和雇用时间
select ename,hiredate from emp where extract(year from hiredate)=1981;
7.选择公司中没有管理者的员工姓名及job
select ename,job from emp where mgr is null;
8.选择公司中有奖金的员工姓名,工资和奖金级别
select ename,sal,comm from emp where nvl(comm,0)!=0;
9.选择员工姓名的第三个字母是a的员工姓名
select ename from emp where ename like '__A%';
10.选择姓名中有字母a和e的员工姓名
select ename from emp where ename like '%A%' and ename like '%E%';
11.显示系统时间
select sysdate from dual;
12.查询员工号,姓名,工资,以及工资提高百分之20%后的结果
select empno,ename,(sal*1.2) as 提高后的工资 from emp;
13.将员工的姓名按首字母排序,并写出姓名的长度(length)
select ename,length(ename) from emp order by ename;
14.查询各员工的姓名,并显示出各员工在公司入职的月份数
select ename,extract(month from hiredate) from emp;
15.查询员工的姓名,以及在公司入职的月份数(worked_month),并按月份数降序排列
select ename,extract(month from hiredate) from emp order by extract(month from hiredate) desc;
16.查询公司员工工资的最大值,最小值,平均值,总和
select max(sal),min(sal),avg(sal),sum(sal) from emp;
17.查询各工种(job)的员工工资的最大值,最小值,平均值,总和
select job,max(sal),sum(sal) from emp group by job;
18.选择各个工种(job)的员工人数
select job,count(empno) from emp group by job;
19.查询员工最高工资和最低工资的差距(DIFFERENCE)
select max(sal)-min(sal) from emp;
20.查询各个管理者手下员工的最低工资,其中最低工资不能低于1500,没有管理者的员工不计算在内
--分析
--查询员工
select * from emp;
select mgr,min(sal) from emp group by mgr having mgr is not null and min(sal)>=1500;
21.查询所有部门的名字,工作地点,员工数量和工资平均值.
select * from dept left outer join emp on dept.deptno =emp.deptno;
select dept.dname,dept.loc,count(emp.empno),avg(emp.sal) from dept left outer join emp on dept.deptno =emp.deptno group by dname,loc;
22. 查询和scott相同部门的员工姓名和雇用日期
select deptno from emp where emp.ename='SCOTT';
select ename,hiredate from emp where deptno =(select deptno from emp where emp.ename='SCOTT');
--等同
select emp.ename,emp.hiredate from emp,(select deptno from emp where emp.ename='SCOTT') tmp where emp.deptno=tmp.deptno;
23. 查询工资比公司平均工资高的员工的员工号,姓名和工资。
select avg(sal) from emp;
select empno,sal from emp;
select empno,sal from emp where sal>(select avg(sal) from emp);
24. 查询各部门中工资比本部门平均工资高的员工的员工号,姓名和工资
select deptno,avg(sal) from emp group by deptno;
select empno,sal from emp;
--连表查询
select empno,tmp.vagsal,emp.deptno from emp,(select deptno,avg(sal) as vagsal from emp group by deptno) tmp
where emp.deptno=tmp.deptno and emp.sal>tmp.vagsal;
25. 查询和姓名中包含字母u的员工在相同部门的员工的员工号和姓名
select ename,deptno from emp where ename like '%U%';
select empno,deptno from emp;
--连接表
select emp.empno,emp.ename,(select deptno from emp where ename like '%U%') tmp
where emp.deptno=tmp.deptno;
26. 查询管理者是King的员工姓名和工资
--子查询
select empno from emp where ename='KING';
--这种写法的前提,名字不能相同
select ename,mgr from emp where mgr=(select empno from emp where ename='KING');
27. 使用PL/sql实现9*9的乘法口诀表
set serveroutput on;
begin
for i in 1..9
loop
for j in 1..i
loop
--不换行使用put
dbms_output.put(i ||'*'||j||'='|| (i*j)||' ');
end loop;
--换行
dbms_output.new_line();
end loop;
end;
优化
@H_
404_14@1、
查两张以上表时,把记录少的放在右边
@H_
404_14@2、
WHERE子句中的连接顺序
@H_
404_14@ORACLE采用自上而下的顺序解析WHERE子句,根据这个原则,那些可以过滤掉
最大数量记录的条件应写在WHERE子句
最后。
@H_
404_14@
例如:查询员工的编号,姓名,工资,部门名
@H_
404_14@
如果emp.sal>1500能过滤掉半数记录的话,
@H_
404_14@select emp.empno,emp.sal,dept.dname
@H_
404_14@from emp,dept
@H_
404_14@where (emp.deptno = dept.deptno) and (emp.sal > 1500)
@H_
404_14@.......
@H_
404_14@3、
SELECT子句中避免使用*号
@H_
404_14@ORACLE在解析的过程中,会将*依次转换成所有的列名,这个工作是通过
查询数据字典完成的,这意味着将耗费更多的时间
@H_
404_14@4、
避免对大表进行无条件或无索引的的扫描
@H_
404_14@5、
清空表时用TRUNCATE替代DELETE
@H_
404_14@6、
尽量多使用COMMIT;因为COMMIT会释放回滚点
@H_
404_14@7、
用索引提高查询效率,善用索引
@H_
404_14@
避免在索引列上使用NOT;因为Oracle服务器遇到NOT后,他就会停止目前的工作,转而执行全表扫描。
@H_
404_14@避免在索引列上使用计算;WHERE子句中,如果索引列是
函数的一部分,优化器将不使用索引而使用全表扫描,这样会变得慢
@H_
404_14@
例如,SAL列上有索引,
@H_
404_14@
低效:
@H_
404_14@SELECT EMPNO,ENAME
@H_
404_14@FROM EMP
@H_
404_14@WHERE SAL*12 > 24000;
@H_
404_14@
高效:
@H_
404_14@SELECT EMPNO,ENAME
@H_
404_14@FROM EMP
@H_
404_14@WHERE SAL > 24000/12;
@H_
404_14@8、
字符串型,能用=号,不用like;=号表示精确比较,like表示模糊比较
@H_
404_14@9、
用 >= 替代 >
@H_
404_14@低效:
@H_
404_14@SELECT * FROM EMP WHERE DEPTNO > 3
@H_
404_14@
首先定位到DEPTNO=3的记录并且扫描到第一个DEPT大于3的记录
@H_
404_14@
高效:
@H_
404_14@SELECT * FROM EMP WHERE DEPTNO >= 4
@H_
404_14@
直接跳到第一个DEPT等于4的记录
@H_
404_14@10、
用IN替代OR
@H_
404_14@select * from emp where sal = 1500 or sal = 3000 or sal = 800;
@H_
404_14@select * from emp where sal in (1500,3000,800);
@H_
404_14@11、
用exists代替in;not exists代替 not in
@H_
404_14@not in 字句将执行一个内部的排序和合并,任何情况下,not in是最低效的,子
查询中全表扫描;表连接比exists更高效
@H_
404_14@12、
用UNION-ALL 替换UNION
@H_
404_14@
当sql语句需要UNION两个
查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并,然后在
输出最终结果前进行排序. 如果用UNION ALL替代UNION,这样排序就不是必要了. 效率会因此得到提高。
@H_
404_14@13、
避免使用耗费资源的操作
@H_
404_14@
带有DISTINCT,UNION,MINUS,INTERSECT的
sql语句会启动
sql引擎 执行耗费资源的排序(SORT)
功能. DISTINCT需要一次排序操作,而其他的至少需要执行两次排序. 通常,
带有UNION,INTERSECT的sql语句都可以用其他方式重写。
@H_
404_14@最后;同样的操作有些时候可以在程序上处理的就程序上处理,毕竟在内存中的执行速度比在硬盘上执行要高非常多。