Oracle的练习与优化

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,(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),min(sal),avg(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,ename,sal from emp;
select empno,ename,sal from emp where sal>(select avg(sal) from emp);
 
 
24.	查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资
select deptno,avg(sal) from emp group by deptno;
 
select empno,ename,sal from emp;
 
--连表查询
select empno,ename,sal, 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,ename,deptno from emp;
 
--连接表
select emp.empno,emp.ename,emp.deptno from emp,(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,sal,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;
 


优化

1、 查两张以上表时,把记录少的放在右边

2、 WHERE子句中的连接顺序

ORACLE采用自上而下的顺序解析WHERE子句,根据这个原则,那些可以过滤掉最大数量记录的条件应写在WHERE子句最后  

例如:查询员工的编号,姓名,工资,部门名  

      如果emp.sal>1500能过滤掉半数记录的话,

      select emp.empno,emp.ename,emp.sal,dept.dname

      from emp,dept

      where (emp.deptno = dept.deptno) and (emp.sal > 1500)

             .......  

3、 SELECT子句中避免使用*号

ORACLE在解析的过程中,会将*依次转换成所有的列名,这个工作是通过查询数据字典完成的,这意味着将耗费更多的时间

4、 避免对大表进行无条件或无索引的的扫描

5、 清空表时用TRUNCATE替代DELETE

6、 尽量多使用COMMIT;因为COMMIT会释放回滚点

7、 用索引提高查询效率,善用索引

避免在索引列上使用NOT;因为Oracle服务器遇到NOT后,他就会停止目前的工作,转而执行全表扫描。

避免在索引列上使用计算;WHERE子句中,如果索引列是函数的一部分,优化器将不使用索引而使用全表扫描,这样会变得慢

      例如,SAL列上有索引,

      低效:

      SELECT EMPNO,ENAME

      FROM EMP

      WHERE SAL*12 > 24000;

      高效:

      SELECT EMPNO,ENAME

      FROM EMP

      WHERE SAL > 24000/12;

8、 字符串型,能用=号,不用like=号表示精确比较,like表示模糊比较

9、  >= 替代 >

低效:

      SELECT * FROM EMP WHERE DEPTNO > 3   

      首先定位到DEPTNO=3的记录并且扫描到第一个DEPT大于3的记录

      高效:

      SELECT * FROM EMP WHERE DEPTNO >= 4  

      直接跳到第一个DEPT等于4的记录

10、 IN替代OR

select * from emp where sal = 1500 or sal = 3000 or sal = 800;

select * from emp where sal in (1500,3000,800);

11、 exists代替in;not exists代替 not in

not in 字句将执行一个内部的排序和合并,任何情况下,not in是最低效的,子查询中全表扫描;表连接比exists更高效

12、 UNION-ALL 替换UNION

SQL语句需要UNION两个查询结果集合时,这两个结果集合会以UNION-ALL的方式被合并, 然后在输出最终结果前进行排序. 如果用UNION ALL替代UNION, 这样排序就不是必要了. 效率会因此得到提高。

13、 避免使用耗费资源的操作

带有DISTINCT,UNION,MINUS,INTERSECT的SQL语句会启动SQL引擎 执行耗费资源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要执行两次排序. 通常, 带有UNION, MINUS , INTERSECT的SQL语句都可以用其他方式重写。

 

最后;同样的操作有些时候可以在程序上处理的就程序上处理,毕竟在内存中的执行速度比在硬盘上执行要高非常多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值