oracle_sql_练习

oracle_sql_练习
2009年12月08日 星期二 14:32
(1)总结理解ORACLE软件安装步骤,注意事项
(2)总结理解建库步骤,注意事项
(3)注意区分一下几个概念:
ORACLE SERVER --> a machine running oracle(almost only running oracle)
/--INSTANCE --> 一段内存(是访问数据库的途径(媒介))
/--ORACLE DB --> oracle databases
GLOBAL DB NAME --> 全局数据库名称(db_name,db_domain),唯一标识数据库名字
/--db_name
/--db_domain
ORACLE_SID --> 作为环境变量,指定实例名称
(4)把服务器和客户端2台机器安装配置好





[题01] 请找出薪资大于2500的员工的信息且将结果倒序输出,要求显示员工姓名。
考点:
1>理解sal>2500执行过程
2>select 列和 order by 列 的关系
3>order by后面可接的3种方式

SQL> select ename,sal from emp
2 where sal>2500
3 order by sal desc;

ENAME             SAL
---------- ----------
BLAKE            2850
JONES            2975
FORD             3000
SCOTT            3000
KING             5000


[题02] 请找出所有员工的姓名并显示ul_xxx_ok字样.    ,显示形如ul_smith_ok..的字样.注意smith是小写
考点:
1>concat和lower函数的使用
2>理解基于函数时的SQL执行过程
3>理解concat和lower各执行的次数
4>理解函数永远返回值
5>函数的嵌套
SQL> select concat(lower(concat('ul_',ename)),'_ok') from emp;

CONCAT(LOWER(CON
----------------
ul_smith_ok
ul_allen_ok
ul_ward_ok
或者:
SQL> select 'ul_'||lower(ename)||'_ok' newname from emp;

NEWNAME
----------------
ul_allen_ok
ul_ward_ok
ul_jones_ok


[题03] 请找出81年7月以后入职的人有哪些?显示姓名,日期(用三种思想)
考点:
1>to_date和to_char灵活使用
2>日期和字符串的隐式转换
3>找出最好的语句
SQL> select ename,hiredate from emp
2 where to_char(hiredate,'yyyy-mm-dd')>'1981-07-01';

ENAME      HIREDATE
---------- -------------------
MARTIN     1981-09-28 00:00:00
SCOTT      1987-04-19 00:00:00
KING       1981-11-17 00:00:00
TURNER     1981-09-08 00:00:00
ADAMS      1987-05-23 00:00:00
JAMES      1981-12-03 00:00:00
FORD       1981-12-03 00:00:00
MILLER     1982-01-23 00:00:00

8 rows selected.



[题04] 清找出近三个月入职的人有哪些?显示姓名,日期(用两种思想)
考点:
1>months_between的使用
2>add_months的使用
SQL> select max(hiredate) from emp;

MAX(HIREDATE)
-------------------
1987-05-23 00:00:00

SQL> select ename,hiredate from emp
2 where hiredate between '1987-03-01' and '1987-05-23';

ENAME      HIREDATE
---------- -------------------
SCOTT      1987-04-19 00:00:00
ADAMS      1987-05-23 00:00:00


[题05] 请计算每个人入职年数,保留小数点1位(末尾数直接进数).并且按照入职的年数倒序输出
考点:
1>months_between和ceil使用
2>函数的嵌入使用
3>有关计算年的思路(工作中常用)
SQL> select round((sysdate-hiredate)/365,1) as work_years
2 from emp
3 order by work_years desc;

WORK_YEARS
----------
29
28.8
28.8
28.7
28.6
28.5
28.3
28.2
28.1
28
28

WORK_YEARS
----------
27.9
22.6
22.5

14 rows selected.




[题06] 请根据每个人的job计算其调薪前和调薪后的情况。显示姓名,调薪前、调薪后(调薪的标准如下)
PRESIDENT=>原来的1.1倍   MANAGER=>原来的1.2倍   ANALYST=>原来的1.3倍 其余=>原来的1.4倍
考点:
1>decode简单使用
SQL> select ename,sal,decode(
2 job,'PRESIDENT',sal*1.1,
3 'MANAGER',sal*1.2,
4 'ANALYST',sal*1.3,
5 'SALESMAN',SAL*1.4,
6 'CLERK',sal*1.4,sal)
7 as "increase" from emp; ####注意,这里的"increase"要用""号,不能用''号.

ENAME             SAL   increase
---------- ---------- ----------
SMITH             800       1120
ALLEN            1600       2240
WARD             1250       1750
JONES            2975       3570
MARTIN           1250       1750
BLAKE            2850       3420


[题07] 请统计历史数据中每个季度入职人数(不考虑年数的不同),显示季度数,入职人数(如果某季度没有人数则不用显示)
考点:
1>decode思路扩展
2>分组的使用
3>group by需要注意的几点
SQL> select sum(decode(to_char(hiredate,'fmmm'),1,1,2,1,3,1,0)) season_1,
2 sum(decode(to_char(hiredate,'fmmm'),4,2,5,2,6,2,0)) season_2,
3 sum(decode(to_char(hiredate,'fmmm'),7,3,8,3,9,3,0)) season_3,
4 sum(decode(to_char(hiredate,'fmmm'),10,4,11,4,12,4,0)) season_4 from emp;

SEASON_1   SEASON_2   SEASON_3   SEASON_4
---------- ---------- ---------- ----------
3         10          6         16



[题08]请找出每个部门中薪资最高的人和薪资最低的人,显示部门名称,员工姓名,员工最高薪资|最低薪资
考点:
1>子查询
2>in
3>union|union all
SQL> select deptno,ename,sal from emp
2 where sal in (select max(sal) from emp group by deptno) or sal in (select min(sal) from emp group by deptno)
3 order by deptno;

DEPTNO ENAME             SAL
---------- ---------- ----------
10 KING             5000
10 MILLER           1300
20 SCOTT            3000
20 FORD             3000
20 SMITH             800
30 JAMES             950
30 BLAKE            2850

7 rows selected.


[题09] 请分别用两种格式显示1980 ~1983年之间的每年的入职人数。
-----------------------------
1980   x
1981   y
1982   z
-----------------------------
1980 1981   1982
x     y    z  
考点:
1>经典的行转列问题
2>分组和聚合函数
SQL> select to_char(hiredate,'yyyy'),count(*) from emp
2 group by to_char(hiredate,'yyyy');

TO_C   COUNT(*)
---- ----------
1987          2
1
1982          1
1981          8

SQL> select sum(decode(to_char(hiredate,'yyyy'),'1980',1,0)) "1980",
2 sum(decode(to_char(hiredate,'yyyy'),'1981',1,0)) "1981",
3 sum(decode(to_char(hiredate,'yyyy'),'1982',1,0)) "1982",
4 sum(decode(to_char(hiredate,'yyyy'),'1987',1,0)) "1987"
5 from emp;

1980       1981       1982       1987
---------- ---------- ---------- ----------
0          8          1          2



[题10] 请找出哪个部门的员工薪资大于2500,显示部门名称即可.(要求用两种思想)
1>深入理解exists的运行过程
SQL> select d.dname from dept d
2 where exists (select 'x' from emp e where e.deptno=d.deptno
3 and e.sal>2500);

DNAME
--------------
ACCOUNTING
RESEARCH
SALES



[题11] 请找出被领导者的薪资高于(直接)领导者的薪资,显示其被领导者姓名和薪资(要求用两种思想分别实现)
考点:
1>自连接
2>深入理解exists的运行过程
1>自连接:
SQL> select e.ename,e.sal from emp em,emp e
2 where em.empno=e.mgr and e.sal>em.sal;

ENAME             SAL
---------- ----------
SCOTT            3000
FORD             3000


查询不直接领导同事的员工的信息(即有上司无下属),包括工号,名字,薪水和领导者:
SQL> select e.empno,e.ename,e.sal,e.mgr from emp e
2 where e.empno not in
3 (select distinct mgr from emp where mgr is not null);

EMPNO ENAME             SAL        MGR
---------- ---------- ---------- ----------
111
7844 TURNER           1500       7698
7934 MILLER           1300       7782
7902 FORD             3000       7566
7654 MARTIN           1250       7698
7876 ADAMS            1100       7788
7900 JAMES             950       7698

7 rows selected.



[题12] 请找出哪个部门未分配员工,只显示部门名称即可.(要求用三种思想分别实现)
请统计所有部门的人数,显示部门名称、部门人数.(注意是所有部门)
SQL> select d.dname from dept d
2 where not exists
3 (select 'x' from emp e where e.deptno=d.deptno);

DNAME
--------------
OPERATIONS

请统计所有部门的人数,显示部门名称、部门人数.(注意是所有部门)
SQL> select d.dname,x.count from dept d,
2 (select deptno,count(*) count from emp group by deptno) x
3 where d.deptno=x.deptno(+);

DNAME               COUNT
-------------- ----------
ACCOUNTING              3
RESEARCH                4
SALES                   4
OPERATIONS



[题13] 请找出部门人数超过3人的部门里的人员名单,要求显示部门名称、显示姓名。
考点:
1>exists使用
SQL> select d.dname from dept d
2 where exists
3 (select deptno,count(*) from emp group by deptno
4 having count(*)>3);

DNAME
--------------
ACCOUNTING
RESEARCH
SALES
OPERATIONS



[题14] 找出比本部门平均薪资高的员工姓名和薪资以及部门名称和部门的平均薪资
考点:
1>内部视图使用及相关注意事项
2>等值链接
SQL> select e.ename,e.sal,x.dname,x.avgsal from
2 (select d.dname,d.deptno,t.avgsal from dept d,
3 (select deptno,avg(sal) avgsal from emp group by deptno) t
4 where d.deptno=t.deptno) x,emp e
5 where x.deptno=e.deptno
6 and e.sal>x.avgsal;

ENAME             SAL DNAME              AVGSAL
---------- ---------- -------------- ----------
JONES            2975 RESEARCH          2518.75
BLAKE            2850 SALES              1637.5
SCOTT            3000 RESEARCH          2518.75
KING             5000 ACCOUNTING     2916.66667
FORD             3000 RESEARCH          2518.75



[题15] 请找出公司级薪资的4~5名,要求显示员工姓名,薪资
考点:
1>rownum的使用
2>内部视图的嵌入使用
3>模拟BS结构的分页SQL程序
4>不允许用分析函数实现
SQL> select * from
2 (select ename,sal from emp order by sal desc) x
3 where rownum<6
4 minus
5 select * from
6 (select ename,sal from emp order by sal desc) x
7 where rownum<4;

ENAME             SAL
---------- ----------
FORD             3000
JONES            2975



[题16] 显示每个人的姓名:部门薪资,占部门薪资100%,总薪资,占总薪资的100%
考点:
1>分析函数的使用
2>分析函数运行过程
SQL> select e.ename,d.sum_dept_sal,e.sal/d.sum_dept_sal,
2 a.sum_all_sal,e.sal/a.sum_all_sal from emp e,
3 (select deptno,sum(sal) sum_dept_sal from emp
4 group by deptno) d,
5 (select sum(sal) sum_all_sal from emp) a
6 where e.deptno=d.deptno;

ENAME      SUM_DEPT_SAL E.SAL/D.SUM_DEPT_SAL SUM_ALL_SAL E.SAL/A.SUM_ALL_SAL
---------- ------------ -------------------- ----------- -------------------
JONES             10075                .2953       25375               .1172
MARTIN             6550                .1908       25375               .0493
BLAKE              6550                .4351       25375               .1123
CLARK              8750                .2800       25375               .0966
SCOTT             10075                .2978       25375               .1182
KING               8750                .5714       25375               .1970
TURNER             6550                .2290       25375               .0591
ADAMS             10075                .1092       25375               .0433
JAMES              6550                .1450       25375               .0374
FORD              10075                .2978       25375               .1182
MILLER             8750                .1486       25375               .0512

11 rows selected.




[题17] 请找出每个部门的薪资最后3名。显示部门名称,员工姓名,薪资,部门排名
1>分析函数的使用
1.先得到如下格式(DNAME(部门名)   COUNT_MAN(部门人数统计) AVGSAL(部门平均薪水) ENAME(员工名))的表,理解这个过程:
SQL> select d.dname,x.count_man,x.avgsal,e.ename from
2 dept d,
3 (select deptno,count(ename) count_man,avg(sal) avgsal,min(sal) minsal
4 from emp group by deptno) x,
5 emp e
6 where e.deptno=d.deptno and e.deptno=x.deptno and e.sal=x.minsal;

DNAME           COUNT_MAN     AVGSAL ENAME
-------------- ---------- ---------- ----------
RESEARCH                4    2518.75 ADAMS
SALES                   4     1637.5 JAMES
ACCOUNTING              3 2916.66667 MILLER

SQL> select ename,sal,deptno,rm from
2 (select x.*,row_number() over (partition by x.deptno order by sal
3 desc) rm from emp x)
4   where rm<4;

ENAME             SAL     DEPTNO         RM
---------- ---------- ---------- ----------
KING             5000         10          1
CLARK            2450         10          2
MILLER           1300         10          3
SCOTT            3000         20          1
FORD             3000         20          2
JONES            2975         20          3
BLAKE            2850         30          1
TURNER           1500         30          2
MARTIN           1250         30          3
1

10 rows selected.



[题18]找出全公司薪资的前3名,显示ename,sal:
SQL> select ename,sal from
2 (select ename,sal from emp order by sal desc)
3 where rownum<=3;

ENAME             SAL
---------- ----------
KING             5000
SCOTT            3000
FORD             3000

排名中有相同值的问题处理:
SQL> select empno,ename,
2 rank() over(order by sum(sal) desc) rank,
3 dense_rank() over(order by sum(sal) desc) dense_rank,
4 row_number() over(order by sum(sal) desc) row_number
5 from emp
6 group by empno,ename;

EMPNO ENAME            RANK DENSE_RANK ROW_NUMBER
---------- ---------- ---------- ---------- ----------
111                     1          1          1
7839 KING                2          2          2
7788 SCOTT               3          3          3
7902 FORD                3          3          4
7566 JONES               5          4          5
7698 BLAKE               6          5          6
7782 CLARK               7          6          7
7844 TURNER              8          7          8
7934 MILLER              9          8          9
7654 MARTIN             10          9         10
7876 ADAMS              11         10         11

EMPNO ENAME            RANK DENSE_RANK ROW_NUMBER
---------- ---------- ---------- ---------- ----------
7900 JAMES              12         11         12

12 rows selected.

row_number:返回一个唯一的值,当碰到相同数据,排名按照记录集中的顺序依此递增
(忽略相同的数据,(譬如SCOTT'S SAL=3000,FORD'S SAL=3000,排名则可能是SCOTT=3,FORD=4))
dense_rank:返回一个唯一的值,所有相同的排名待遇一样(譬如排在第3的有2个 --> 1 2 3 3 4 5 ...)
rank:返回一个唯一的值,所有相同的排名都是一样,但是最后一条相同记录和下一条排名之间空出排名
(譬如排在第3的有2个,则第4将不存在,下一个直接到第5 --> 1 2 3 3 5 6 ...)

 

你可能感兴趣的:(oracle,sql,数据库,manager,server,domain)