主结果中的SQL自联接结果(不是单独的列)

时间:2014-01-31 00:30:46

标签: sql sql-server tsql sql-server-2012

使用:SQL Server 2012

我有一个名为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书籍,但到目前为止找不到任何可以帮助我的东西。有人请吗?

2 个答案:

答案 0 :(得分: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给出的答案将起作用。

答案 1 :(得分: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表中。