2014-01-31 33 views
1

使用:SQL Server 2012的SQL自联接结果中的主要结论(未单独列)

我有一个自引用表称为Department这样的:

DepartmentID | Name  | DepartmentParentID 
1    Sales  NULL 
2    Outbound 1 
3    Inbound 1 
4    Showroom 1 

的部门,如InboundShowroom有一个Sales的父系。

我现在需要写一个SQL查询来显示哪些用户在哪个部门。事情是这样的:

SELECT 
    d.DepartmentID, d.DepartmentName, d2.DepartmentParentID, d2.DepartmentName 
FROM 
    [User_Department] ud ---table that maps users to departments 
INNER JOIN 
    [Department] d1 ON d1.DepartmentID = ud.DepartmentID 
LEFT JOIN 
    [Department] d2 ON d2.DepartmentID = d1.DepartmentParentID ---this has gone horribly wrong 
WHERE 
    ud.Username = @Username 

忘记了LEFT JOIN在上面的代码中的一部分,现在,我会得到这样的结果:

Username | DepartmentName 
DannySmith  Inbound 
DannySmith  Outbound 

但我需要的是上级部门也表现出在DepartmentName的列表(这就是我想要的)

Username | DepartmentName 
DannySmith  Sales 
DannySmith  Inbound 
DannySmith  Outbound 

这是如何实现的可能。我不希望上级部门要在这样一个单独的列(这是我不希望):

Username | DepartmentName | DepartmentName 
DannySmith  Inbound   Sales 
DannySmith  Outbound   Sales 

一直在试图查看某些SQL的书籍,但无法找到任何东西那可以帮助我至今。请人吗?

+0

哪个部门'Dany Smith'映射到你的'User_Department'表中? –

回答

3

如果您有多层次的层次结构的可能性,您应该使用递归公用表表达式。例如,如果在“Showroom”,“Inbound”或“Outbound”中可能有子部门。

;WITH CTE AS (
    SELECT 
    ud.UserName, d.DepartmentID, d.Name, d.DepartmentParentID 
    FROM 
    [User_Department] ud 
    INNER JOIN 
    [Department] d ON d.DepartmentID = ud.DepartmentID 
    UNION ALL 
    SELECT 
    CTE.UserName, d.DepartmentID, d.Name, d.DepartmentParentID 
    FROM 
    [Department] d 
    INNER JOIN 
    [CTE] on CTE.DepartmentParentId = d.DepartmentID 
) 
SELECT distinct UserName, DepartmentId, Name 
FROM CTE 
WHERE 
    Username = 'DannySmith' 

如果您确定只有一个层次的层次结构,那么@sgeddes给出的答案将起作用。

+0

你是对的,可能有多层次的层次结构,所以这是一个非常好的答案 –

1

一种选择是使用UNION(这也使用了公共表表达式,这使得它更容易一些阅读):

WITH CTE AS (
    SELECT 
    ud.UserName, d.DepartmentID, d.DepartmentName, d.DepartmentParentID 
    FROM 
    [User_Department] ud 
    INNER JOIN 
    [Department] d ON d.DepartmentID = ud.DepartmentID 
    WHERE 
    ud.Username = @Username 
) 
SELECT UserName, DepartmentId, DepartmentName 
FROM CTE 
UNION 
SELECT C.UserName, D.DepartmentId, D.DepartmentName 
FROM Department D 
    JOIN CTE C ON D.DepartmentId = C.DepartmentParentID 

顺便说一句 - 如果我解释您的表格定义正确,您的UserName字段应该可能位于其自己的User表格中。

+0

谢谢你sgeddes。我的用户名是用户的另一个表。这只是一个连接表,所以它也具有作为外键的用户名。 –