使用:SQL Server 2012
我有一个名为Department
的自引用表,如下所示:
DepartmentID | Name | DepartmentParentID
1 Sales NULL
2 Outbound 1
3 Inbound 1
4 Showroom 1
Inbound
和Showroom
等部门的主管部门为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 :(得分: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
表中。