[數據庫]關於三個比較典型的數據庫試題(1.找到員工表中工資最高的前三名;2.找到員工表中薪水大於本部門平均薪水的員工;3.統計每年入職的員工個數)


最近學習Oracle,老師講了三個比較典型的問題,做一下總結,也便於以后復習.

下圖顯示的是三個題的題干和要查詢的結果:

===========================================第一題============================
找到員工表中工資最高的前三名:

先說明一個現象:

 1 SQL> select rownum,ename from emp;
 2 
 3 ROWNUM ENAME
 4 ---------- ----------
 5 1 SMITH
 6 2 ALLEN
 7 3 WARD
 8 4 JONES
 9 5 MARTIN
10 6 BLAKE
11 7 CLARK
12 8 SCOTT
13 9 KING
14 10 TURNER
15 11 ADAMS
16 12 JAMES
17 13 FORD
18 14 MILLER

如果在加上order by排序的條件限制:

 1 SQL> select rownum ,ename,sal from emp order by sal desc;
 2 
 3     ROWNUM ENAME             SAL
 4 ---------- ---------- ----------
 5          9 KING             5000
 6         13 FORD             3000
 7          8 SCOTT            3000
 8          4 JONES            2975
 9          6 BLAKE            2850
10          7 CLARK            2450
11          2 ALLEN            1600
12         10 TURNER           1500
13         14 MILLER           1300
14          3 WARD             1250
15          5 MARTIN           1250
16         11 ADAMS            1100
17         12 JAMES             950
18          1 SMITH             800

加上order by 之后rownum 依舊沒有變化,說明rownum是基於原始表emp進行排序的 ,固定住了,所以如下使用rownum<=3 來取得Top3是錯誤的:

SQL> select rownum,empno,ename,sal
  2  from emp
  3  where rownum<=3
  4  order by sal desc;

    ROWNUM      EMPNO ENAME             SAL                                                                                                           
---------- ---------- ---------- ----------                                                                                                           
         2       7499 ALLEN            1600                                                                                                           
         3       7521 WARD             1250                                                                                                           
         1       7369 SMITH             800    

 

只要是表中的數據內容沒有變,每條記錄對應的行號rownum就不會變....

這個地方可以引出Oracle中的分頁問題:

具體可以看我在博客中的總結:

 http://www.cnblogs.com/DreamDrive/p/4025112.html

把這個select ename,sal from emp order by sal desc查詢的結果集再看成一個新表

用rownum就會對這個新表進行排序.排序的rownum按照查詢的順序來展示.

select rownum,ename,sal from
    (select ename,sal from emp order by sal desc) 
    where rownum < 4

    ROWNUM ENAME             SAL
---------- ---------- ----------
         1 KING             5000
         2 SCOTT            3000
         3 FORD             3000

===========================================第二題===================================

找到員工表中薪水大於本部門平均薪水的員工

SQL> select e.empno,e.ename,e.sal,d.avgsal
     from  emp e,(select deptno,avg(sal) avgsal from emp group by deptno) d
     where e.deptno=d.deptno and e.sal>d.avgsal;

     EMPNO ENAME             SAL     AVGSAL
---------- ---------- ---------- ----------
      7499 ALLEN            1600 1566.66667
      7566 JONES            2975       2175
      7698 BLAKE            2850 1566.66667
      7788 SCOTT            3000       2175
      7839 KING             5000 2916.66667
      7902 FORD             3000       2175

e.deptno = empavg.deptno and e.sal > empavg.salavg
翻譯下來就是:第一個條件是本部門的員工,第二個是薪水大於部門的平均薪水

還有一種不用group by分組函數也能查詢到

叫:相關子查詢

相關子查詢:將主查詢中的某些值作為參數傳遞給子查詢.

相關子查詢對外邊的主表有一個要求,必須有一個別名.

 

先不看上面結果的第四列(AVGSAL),可以很容易的查詢到

select empno,ename, sal from emp e

 

然后查詢某個部門的平均工資:

select avg(sal) from emp where deptno = ?

 

需要確定這個deptno是什么!

結合上面兩個語句

select empno,ename, sal from emp e

where e.sal >( select avg(sal) from emp where deptno = ?)

這個問好?應該代表的是查詢的當前員工所在的部門號傳給這個問號.

變成:

select empno,ename, sal from emp e

where e.sal > (select avg(sal) from emp where deptno = e.deptno);

 

然后主查詢列上要加上所在部門平均工資

把上面的最后一句查詢部門的平均工資拷貝到主查詢列上.就可以了.

 

SQL> select empno,ename, sal,(select avg( sal) from emp  where deptno = e.deptno) avgsal
      from emp e
      where e.sal>(select avg( sal) from emp  where deptno = e.deptno);

     EMPNO ENAME             SAL     AVGSAL
---------- ---------- ---------- ----------
      7499 ALLEN            1600 1566.66667
      7566 JONES            2975       2175
      7698 BLAKE            2850 1566.66667
      7788 SCOTT            3000       2175
      7839 KING             5000 2916.66667
      7902 FORD             3000       2175

 

===============================================第三題=======================
統計每年入職的員工的個數!

select count(*) from emp where decode(substr(to_char(hiredate,'yyyy-mm-dd'),3,2)80


decode(substr(to_char(hiredate,"yyyy-mm-dd"),3,4),'81',count+1)


SQL> select count(*) ,
2 sum(decode(to_char(hiredate,'RR'),'80',1,0)) "1980",
3 sum(decode(to_char(hiredate,'RR'),'81',1,0)) "1981",
4 sum(decode(to_char(hiredate,'RR'),'87',1,0)) "1987"
5 from emp;

COUNT(*) 1980 1981 1987
---------- ---------- ---------- ----------
14 1 10 2

 



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM