SQL Query显示分层数据

时间:2013-07-24 08:59:45

标签: sql tsql recursive-query

我有两个表 - '用户'和'监督'

对于此示例,我的users表非常简单: -

Users
=====
ID (PK)
UserName

有些用户管理其他用户,所以我建立了第二个表'监督'来管理它: -

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

此表用于将Users表连接到自身以标识特定的用户主管。可能是用户有多个主管,因此这个表可以完美地用于此目的。

以下是“用户”中的示例数据: -

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

如果我想看看谁直接向Bob报告,编写SQL查询很简单,并告诉我Margaret和Amy是他的直接报告。

我想要做的是编写一个查询,显示每个受Bob影响的人,所以它需要查看Bobs直接报告,然后是他们的直接报告,等等 - 这会让Margaret,Amy,艾玛和卡罗尔在这种情况下的结果。

我认为这需要某种递归,但我完全陷入困境..

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

听起来像你需要一个递归CTE。本文作为入门读物,包含了与您所拥有的相似的示例:

http://blog.sqlauthority.com/2012/04/24/sql-server-introduction-to-hierarchical-query-using-a-recursive-cte-a-primer/

希望它有所帮助。

答案 2 :(得分: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