2015-05-11 12 views
0

我有emp表,KING是公司的CEO,他沒有經理。 KING應該得到RANK'1'。 KING是JONES,CLARK,BLAKE的經理。所以這些會得到RANK'2'....等等。爲emp和經理關係如何根據emp表中員工層次給出RANK

中間表:

empno ename mgr 
7566 JONES KING 
7782 CLARK KING 
7698 BLAKE KING 
7900 JAMES BLAKE 
7844 TURNER BLAKE 
7654 MARTIN BLAKE 
7521 WARD BLAKE 
7499 ALLEN BLAKE 
7934 MILLER CLARK 
7902 FORD JONES 
7788 SCOTT JONES 
7876 ADAMS SCOTT 
7369 SMITH FORD 
7839 KING NULL 

最終輸出應該是這樣的:提前

mgr rank  
KING 1 
JONES 2 
CLARK 2 
BLAKE 2 
JAMES 3 
TURNER 3 
MARTIN 3 
WARD 3 
ALLEN 3 
MILLER 3 
SCOTT 3 
FORD 3 
ADAMS 4 
SMITH 4 

感謝。我希望這是在oracle中完成的。

+3

搜索甲骨文的文檔稱爲'LEVEL' – ibre5041

+0

你已經列出了兩個不同的RDBMS,這是真的,還是它必須是數據庫不可知的? SQL語法將因引擎而異。 – xQbert

+0

在MySQL的情況下是沒有辦法的。連接的是Oracle專有的擴展和遞歸CTE(SQL標準)也不受支持。 – ibre5041

回答

2

我花了我的時間來圍繞過去的常見問題,但是,一旦你花時間擺弄他們,他們通常並不那麼強硬。

SQL> with w_data as (
    2   select 7566 empno, rtrim('JONES ') ename, rtrim('KING ') mgr from dual union all 
    3   select 7782 empno, rtrim('CLARK ') ename, rtrim('KING ') mgr from dual union all 
    4   select 7698 empno, rtrim('BLAKE ') ename, rtrim('KING ') mgr from dual union all 
    5   select 7900 empno, rtrim('JAMES ') ename, rtrim('BLAKE') mgr from dual union all 
    6   select 7844 empno, rtrim('TURNER') ename, rtrim('BLAKE') mgr from dual union all 
    7   select 7654 empno, rtrim('MARTIN') ename, rtrim('BLAKE') mgr from dual union all 
    8   select 7521 empno, rtrim('WARD ') ename, rtrim('BLAKE') mgr from dual union all 
    9   select 7499 empno, rtrim('ALLEN ') ename, rtrim('BLAKE') mgr from dual union all 
    10   select 7934 empno, rtrim('MILLER') ename, rtrim('CLARK') mgr from dual union all 
    11   select 7902 empno, rtrim('FORD ') ename, rtrim('JONES') mgr from dual union all 
    12   select 7788 empno, rtrim('SCOTT ') ename, rtrim('JONES') mgr from dual union all 
    13   select 7876 empno, rtrim('ADAMS ') ename, rtrim('SCOTT') mgr from dual union all 
    14   select 7369 empno, rtrim('SMITH ') ename, rtrim('FORD ') mgr from dual union all 
    15   select 7839 empno, rtrim('KING ') ename, NULL   mgr from dual 
    16   ) 
    17 select empno, ename, mgr, level 
    18 from w_data 
    19 connect by mgr = PRIOR ename 
    20 start with mgr IS NULL 
/
    21 
     EMPNO ENAME MGR  LEVEL 
    ---------- ------ ----- ---------- 
     7839 KING     1 
     7698 BLAKE KING   2 
     7499 ALLEN BLAKE   3 
     7900 JAMES BLAKE   3 
     7654 MARTIN BLAKE   3 
     7844 TURNER BLAKE   3 
     7521 WARD BLAKE   3 
     7782 CLARK KING   2 
     7934 MILLER CLARK   3 
     7566 JONES KING   2 
     7902 FORD JONES   3 

     EMPNO ENAME MGR  LEVEL 
    ---------- ------ ----- ---------- 
     7369 SMITH FORD   4 
     7788 SCOTT JONES   3 
     7876 ADAMS SCOTT   4 

    14 rows selected. 

    SQL> 
  • w_data只是僞造了您的測試數據..
  • 由經理=前的ename 連接這需要每一個記錄,而經理與上一級的員工進行比較。
  • 以mgr開頭爲空 這告訴Oracle從哪裏開始...
  • 等級是等級的深度。
+0

謝謝..今天我學習了新的子句CONNECT BY,START WITH。我想知道如何在沒有這個CONNECT BY子句的情況下實現分層查詢。 –

+0

我收到了您的輸入的最終查詢。查詢是: 'SELECT empno,ename,mgr,LEVEL FROM emp CONNECT BY PRIOR empno = mgr START WITH mgr is null' –

+0

使用遞歸公用表表達式可以工作,但mySQL不支持它們。 Oracle在更新的版本中提供。 – xQbert

-2

我相信Oracle在ORDER BY子句中支持CASE WHERE。事情是這樣的:

​​

我相信有一個較短的方式在Oracle中做到這一點(我的經驗是SSMS):

爲`CONNECT BY`條款和僞列
ORDER BY decode(mgr, 'NULL', 1, 'KING', 2, ...) 
+0

感謝您的回覆。這是一個通用的,我使用CONNECT BY子句得到答案。 –

相關問題