2013-07-24 38 views
3

我有两个表 - “用户”和“监督”SQL查询显示heirarchical数据

在这个例子中,我的用户表很简单: -

Users 
===== 
ID (PK) 
UserName 

有些用户管理其他用户,所以我已经建立了第二个表“监督”来管理这样的: -

Supervision 
=========== 
UserID 
SuperID - this is the ID of the staff member that the user supervises. 

此表用于连接用户表与自身识别特定用户主管。这可能是因为一个用户有多个主管,所以这个表完美地完成了这个任务。

这里是我的样本数据中“用户”: -

userID userName 
1  Bob 
2  Margaret 
3  Amy 
4  Emma 
5  Carol 
6  Albert 
7  Robert 
8  Richard 
9  Harry 
10  Arthur 

和我的“监督”的数据: -

userID superID 
1  2 
1  3 
2  4 
2  5 
3  4 
3  5 
6  1 
6  7 
7  8 
7  9 
9  10 

如果我想看到谁直接向鲍勃,写作SQL查询非常简单,并告诉我玛格丽特和艾米是他的直接下属。

然而我想要做的是编写一个查询,显示每个人在Bob下,所以它需要看Bobs直接报告,然后他们的直接报告,等等 - 它会给玛格丽特,艾米,艾玛和卡罗尔作为结果在这种情况下。

我假设这需要某种递归的,但我完全被卡住..

回答

2

你应该使用recursive CTE

WITH RCTE AS 
(
    SELECT * FROM dbo.Supervision WHERE UserID = 1 
    UNION ALL 
    SELECT s.* FROM dbo.Supervision s 
     INNER JOIN RCTE r ON s.userID = r.superID 
) 
SELECT DISTINCT u.userID, u.userName 
FROM RCTE r 
LEFT JOIN dbo.Users u ON r.superID = u.userID 

SQLFiddle DEMO

+0

这是否顾及谁管理,谁在下面,这似乎只带回4分的结果吗? – JsonStatham

+0

@SelectDistinct当然。该例中只有4个结果。尝试为位于层次结构之上的用户6运行它,并且您将得到其下的所有9个其他用户。 http://sqlfiddle.com/#!6/c100f/2 –

+0

啊我看到了,我的答案是否也做同样的事情?我根据OP的例子创建了表格,结果在20分左右,这就是为什么我变得困惑的原因 – JsonStatham

1
WITH MyCTE 
AS ( 

-- ID's and Names 
SELECT SuperID, ID 
FROM Users 
join dbo.Supervision 
on ID = dbo.Supervision.UserID 
WHERE UserID = 1 

UNION ALL 

--Who Manages who... 
SELECT s.SuperID, ID 
FROM Supervision s 
INNER JOIN MyCTE ON s.UserID = MyCTE.SuperID 
WHERE s.UserID IS NOT NULL 

) 

SELECT distinct MyCTE.ID, NAMES.UserName, '<------Reports to ' as Hierarchy, res_name.UserName 
FROM MyCTE 
join dbo.Users NAMES on 
MyCTE.ID = NAMES.ID 

join dbo.Users res_name 
on res_name.ID = MyCTE.SuperID 

order by MyCTE.ID, NAMES.UserName, res_name.UserName