2012-09-14 54 views
1

如何在每個經理記錄下顯示經理ID,經理姓名和下屬細節。如何在經理記錄後顯示經理ID,姓名下屬ID和姓名

EMPNO ENAME JOB  MGR HIREDATE SAL COMM DEPTNO 
----- ------ --------- ---- --------- ---- ---- ------ 
7839 KING PRESIDENT -  17-NOV-81 5000 -  10 
7698 BLAKE MANAGER 7839 01-MAY-81 2850 -  30 
7782 CLARK MANAGER 7839 09-JUN-81 2450 -  10 
7566 JONES MANAGER 7839 02-APR-81 2975 -  20 
7654 MARTIN SALESMAN 7698 28-SEP-81 1250 1400 30 
+0

什麼版本的SQL Server?你想要展示多少個關卡? – RedFilter

+0

@Thomas。 。 。那麼在你上面的數據中,你想讓Martin出現在Blake之下? –

回答

1

試試這個:

WITH MyCTE AS 
( 
    SELECT EMPNO, EName, Null as ManagerId, NULL as ManagerName 
    FROM Employee 
    WHERE ManagerID IS NULL 
    UNION ALL 
    SELECT EMPNO, EName, ManagerId, MyCTE.EName 
    FROM Employee 
    INNER JOIN MyCTE ON Employee.ManagerID = MyCTE.EmpID 
    WHERE Employee.ManagerID IS NOT NULL 
) 
SELECT * 
FROM MyCTE 
+0

我認爲你需要某種訂單才能保證訂購。 –

+0

另外where子句不是必須的 - NULL會被連接消除。仍然是+1,這是做到這一點的方法。 –

+0

沒錯,如果他想要訂購 –

0

這是一個很難的問題,但它是可以解決的。首先,您必須記住,沒有ORDER BY的SQL查詢不保證排序。所以,僅僅因爲它恰好產生正確的結果並不意味着查詢對於你想要的是正確的。

面臨的挑戰是在記錄中添加一個sortkey,以便按照正確的順序進行排列。這是記錄的深度優先排序。其中一個挑戰是三名擁有相同經理的員工需要不同的密鑰 - 因爲他們之間可能會出現其他記錄。

因此,工作的排序鍵是通過生成包含員工ID的頂部路徑來構建的。爲您的數據,密鑰將是:

  • '7839'
  • '7839 < --7698'
  • '7839 < --7782'
  • '7839 < --7566'
  • '7839 < --7698 < --7654'

這些排序按適當的順序。創建密鑰是一個挑戰,需要遞歸CTE。 (謝謝你阿部提供的。)

WITH MyCTE AS 
( 
    SELECT EMPNO, EName, Null as ManagerId, NULL as ManagerName, 
     cast(EMPNO as varchar(8000)) as sortkey 
    FROM Employee 
    WHERE ManagerID IS NULL 
    UNION ALL 
    SELECT EMPNO, EName, ManagerId, MyCTE.EName, 
      mycte.sortkey+'<--'+cast(Employee.empno as varchar(8000)) 
    FROM Employee 
    INNER JOIN MyCTE ON Employee.ManagerID = MyCTE.EmpID 
    WHERE Employee.ManagerID IS NOT NULL 
) 
SELECT EMPNO, EName, ManagerId, MyCTE.EName 
FROM MyCTE 
order by sortkey 

實際排序關鍵字是像上面那些,但與「< - 」追加。一個注意,這隻有當排序鍵正好是4位時才起作用。如果你有不同的長度,那麼你會想要用零填充它們。

+0

是否可以從MyCTE中引用MyCTE.EmpID? – Thomas

1

我想補充的方式,而不CTE,你需要加入你想在每一級別:

select m.empno, 
    m.ename, 
    m.job, 
    e1.empno, 
    e1.ename underling, 
    e1.mgr, 
    e1.ujob, 
    e2.empno, 
    e2.ename subunderling, 
    e2.mgr, 
    e2.subjob 
from 
(
    select empno, ename, job 
    from yourtable 
    where mgr is null 
) m 
left join 
(
    select empno, ename, job ujob, mgr 
    from yourtable 
) e1 
    on m.empno = e1.mgr 
left join 
(
    select empno, ename, job subjob, mgr 
    from yourtable 
) e2 
    on e1.empno = e2.mgr 

看到SQL Fiddle with Demo

相關問題