2011-07-01 53 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

“这有点怪异。 - 你永远不会失望,我的朋友:)。 –