2011-07-01 91 views
0

我有如下表從業人員管理者報告 - SQL服務器

empid empname  managerID 
1   A   NULL 
2   B   1 
3   C   1 
4   D   2 

的DDL是在

Declare @t table(empid int, empname varchar(20), managerID int) 
insert into @t 

select 1,'A',null union all 
select 2,'B',1 union all 
select 3,'C',1 union all 
select 4,'D',2 

我所要做的就是準備一個報告,該報告將顯示哪些員工報告哪位經理。

我一直在使用

select EmpName = e.empname, ManagerName = m.empname 
from @t e 
left join 
@t m 
on e.managerID = m.empid 

soved它和期望的輸出是

EmpName ManagerName 
A   NULL 
B   A 
C   A 
D   B 

什麼是這樣做的其他方式?

回答

0

我認爲,您的解決方案是最合適的,但我們可以把它改寫,如:

select t1.empname [EmpName] 
    , (select t2.empname from @t t2 where t2.empid = t1.managerID) [ManagerName] 
from @t t1 
+0

正確的結果,但一般來說,你應該加入並儘量避免子查詢 – niktrs

+0

@niktrs,我同意。我寫了關於OP的最佳解決方案的意見。 –

0

自加入表

案例1:誰擁有經理

select e1.empname employee, e2.empname manager 
from employee e1 
join employee e2 on e1.managerId = e2.empid 
order by e2.name,e1.name 
所有員工

案例2:所有有管理者的員工

select e1.empname employee, COALESCE(e2.empname,'none') manager 
from employee e1 
left join employee e2 on e1.managerId = e2.empid 
order by e2.name,e1.name 
+0

它會產生錯誤的結果。使用外部連接而不是內部連接。你的查詢和OP的區別是什麼? –

+0

我以爲你只想要管理人員。我寫了兩個選項 – niktrs

+0

我不是主題發起人:-)我只是猜測。 –

1
 
Declare @t table(empid int, empname varchar(20), managerID int) 

insert into @t 
select 1,'A',null union all 
select 2,'B',1 union all 
select 3,'C',1 union all 
select 4,'D',2 

;with CTE AS 
(
    Select empid,empname,managerID, 
    Cast(empname As Varchar(max)) As ReportingManager 
    from @T 
    where managerID is null 

    UNION ALL 

    Select T.empid,T.empname,T.managerID, 
    Cast(CTE.empname+'->'+t.empname As Varchar(max)) As ReportingManager 
    from @T As T 
    INNER JOIN CTE ON T.managerID=CTE.empid 
) 
SELECT * 
FROM CTE 

0

好的,所以你問了其他方法。這有點怪異。

CREATE TABLE employee (empid int, empname varchar(20), managerID int) 
GO 
insert into employee 

select 1,'A',null union all 
select 2,'B',1 union all 
select 3,'C',1 union all 
select 4,'D',2 
GO 

CREATE FUNCTION [dbo].[GetEmployeeTree](@ManagerId int) 
RETURNS XML 
WITH RETURNS NULL ON NULL INPUT 
BEGIN RETURN 
    (SELECT empID as '@Id', 
      empname AS '@Name', 
      dbo.GetEmployeeTree(empid) 
    FROM employee em 
    WHERE [email protected] 
    FOR XML PATH('Employee'), TYPE) 
END 

GO 
SELECT empID as '@Id', 
     empname AS '@Name', 
     dbo.GetEmployeeTree(empId) 
FROM employee 
WHERE managerId is null 
FOR XML PATH('Employee'), ROOT('Employees') 

哪個給出了這樣的輸出

<Employees> 
    <Employee Id="1" Name="A"> 
    <Employee Id="2" Name="B"> 
     <Employee Id="4" Name="D" /> 
    </Employee> 
    <Employee Id="3" Name="C" /> 
    </Employee> 
</Employees> 

其實我已經用它來生成節點數以萬計的大型XML樹,這是相當快的。可能有一種方法可以將根查詢與子查詢合併,但我還沒有完全想到這一點。當我在過去使用這種技術時,我已經使用了一個單獨的鏈接和節點表來定義層次結構,並且當您這樣做時它的工作原理會更清晰一些。

+0

「這有點怪異。 - 你永遠不會失望,我的朋友:)。 –