我有一个包含以下结构的表
userId userName managerId
----------- ---------------- -----------
1 John NULL
2 Charles 1
3 Nicolas NULL
4 Neil 3
我还有另一张表格,其中包含以下内容
userId shareId
----------- -----------
1 1001
3 1002
所以我执行以下查询来获取递归CTE:
WITH UserCTE AS (
SELECT userId, userName, managerId,0 AS steps
FROM dbo.Users
WHERE userId = 7
UNION ALL
SELECT mgr.userId, mgr.userName, mgr.managerId, usr.steps +1 AS steps
FROM UserCTE AS usr
INNER JOIN dbo.Users AS mgr
ON usr.managerId = mgr.userId
)
SELECT * FROM UserCTE AS u;
产生以下结果
userId userName managerId steps
----------- ---------------- ----------- -----------
1 John NULL 0
2 Charles 1 1
3 Nicolas NULL 0
4 Neil 3 1
好的,我想知道的是拥有它的用户的shareId
,以及属于它们的用户。
预期结果:
userId userName managerId steps shareId
----------- ---------------- ----------- ----------- ----------
1 John NULL 0 1001
2 Charles 1 1 1001
3 Nicolas NULL 0 1002
4 Neil 3 1 1002
有没有办法实现它?
由于
答案 0 :(得分:3)
在Share table
的锚点查询中加入Users
Recursive CTE
表。试试这个。
;WITH UserCTE
AS (SELECT c.userId,
userName,
managerId,
0 AS steps,
shareId
FROM dbo.Users c
LEFT JOIN share_table s
ON c.userId = s.userId
WHERE managerId IS NULL
UNION ALL
SELECT mgr.userId,
mgr.userName,
mgr.managerId,
usr.steps + 1 AS steps,
usr.shareId
FROM UserCTE AS usr
INNER JOIN dbo.Users AS mgr
ON usr.userId = mgr.managerId)
SELECT *
FROM UserCTE AS u
ORDER BY userId;
答案 1 :(得分:1)
你可以在cte table和usershare table上做left join
。
WITH UserCTE AS (
SELECT userId, userName, managerId,0 AS steps
FROM dbo.Users
where managerId IS NULL
UNION ALL
SELECT mgr.userId, mgr.userName, mgr.managerId, usr.steps +1 AS steps
FROM UserCTE AS usr
INNER JOIN dbo.Users AS mgr
ON usr.userId = mgr.managerId
)
SELECT * FROM UserCTE AS u
left join userShare us
on u.managerId = us.userId
or u.userId = us.userId
order by u.userId
答案 2 :(得分:1)
一种方法是在OR
表和UserCTE
表之间的连接中使用share
。例如:
WITH UserCTE AS (
SELECT userId, userName, managerId,0 AS steps
FROM dbo.Users
WHERE userId = 7
UNION ALL
SELECT mgr.userId, mgr.userName, mgr.managerId, usr.steps +1 AS steps
FROM UserCTE AS usr
INNER JOIN dbo.Users AS mgr
ON usr.managerId = mgr.userId
)
SELECT * FROM UserCTE AS u
INNER JOIN [share table] AS s
ON u.userId = s.userId OR u.managerId s.userId;
但是,如果存在多个级别的管理层次结构,则可能会重复过程。即经理也有经理。另一种方法是将userId
表的UserCTE
列中的两个左联接一个添加到share
表,将另一个联接到managerId
UserCTE
列的share
列表到CASE
表。然后,您可以使用shareId
列上的WITH UserCTE AS (
SELECT userId, userName, managerId,0 AS steps
FROM dbo.Users
WHERE userId = 7
UNION ALL
SELECT mgr.userId, mgr.userName, mgr.managerId, usr.steps +1 AS steps
FROM UserCTE AS usr
INNER JOIN dbo.Users AS mgr
ON usr.managerId = mgr.userId
)
SELECT
u.*
,CASE
WHEN su.shareId is not null THEN su.shareId
WHEN sm.shareId is not null THEN sm.shareId
ELSE null END as shareID
FROM UserCTE AS u
LEFT JOIN [share table] AS su
ON u.userId = s.userId
LEFT JOIN [share table] AS sm
ON u.managerId = s.userId;
语句来决定您需要哪一项。见下文:
{{1}}
希望这有帮助。