Ale*_*ith 6 sql recursion sql-server-2005 common-table-expression correlated-subquery
我遇到一种情况,我需要能够查看给定的人是否在用户/经理层次结构中。
我需要能够根据一组规则为一组用户执行此操作(不用担心这一点,只是为了给它一些背景信息)
理想情况下,我想在 where 子句的相关存在子查询中使用递归 CTE。
但这会带来很多问题..
我想我想做的是:
WITH UserHierarchy(UserId, ManagerId)
AS
(
--Anchor Definition
SELECT [UserId], [ManagerId] FROM [Users] WHERE [ManagerId] = [Rules].[RuleAddedByUserId] -- this needs to bind to an outer query....
UNION ALL
--Recursive Member definiation
SELECT [Users].[UserId], [Users].[ManagerId] FROM [Users]
INNER JOIN [UserHierarchy] ON [Users].[ManagerId] = [UserHierarchy].[UserId]
WHERE [Users].[UserId] <> [Users].[ManagerId] --don't recurse if the anchor definition matches itself (to avoid an infinate loop).
)
Run Code Online (Sandbox Code Playgroud)
无论如何,是否可以在兼容模式 80 下使锚点定义动态化?或者另一种方法?
我终于到了那里!谢谢大家的帮助。
这是我正在处理的 SQL 的片段。
我只需要改变我的想法,而不是查看 where 子句中的管理器下是否存在用户。我需要将 CTE 视为预过滤器并构建我之前需要的所有详细信息,然后在存在语句之后进行正常过滤(注意,为了简洁起见,我没有包含这些语句)。
RulesUserHierarchy(UserId, ManagerId, PushRuleId, OnlyForSubOrdinates) -- Gets only subordinates for rules created by managers. And all users for those created by admin.
AS
(
--Anchor Definition
SELECT
[Users].[UserId]
,[Users].[ManagerId]
,[RulesAnchor].[PushRuleId]
,[RulesAnchor].[OnlyForSubOrdinates]
FROM [Users]
CROSS JOIN [Rules] [RulesAnchor] --assume every user is doing every rule at this point (because the recursive statement has to be the first statement), we'll filter later.
WHERE (([OnlyForSubOrdinates]) = 0 OR ([OnlyForSubOrdinates] = 1 AND [UserId] = [RulesAnchor].[AddedByUserId]))
UNION ALL
--Recursive Member definiation
SELECT
[Users].[UserId]
,[Users].[ManagerId]
,[RulesUserHierarchy].[PushRuleId]
,[RulesUserHierarchy].[OnlyForSubOrdinates]
FROM [Users]
INNER JOIN [RulesUserHierarchy]
ON [Users].[ManagerId] = [RulesUserHierarchy].[UserId] --recursive hook
AND [RulesUserHierarchy].[OnlyForSubOrdinates] = 1 -- no point recursing if it's for everyone, as the anchor will pull back everything for us.
WHERE [Users].[UserId] <> [Users].[ManagerId] --don't recurse if the anchor definition matches itself (to avoid an infinate loop).
)
-- simple statement to test recursion above, will be filtering the inclusions here (e.g. the other mega exists statements)
SELECT [UserId], [ManagerId], [PushRuleId], [OnlyForSubOrdinates] FROM [RulesUserHierarchy]
Run Code Online (Sandbox Code Playgroud)
编辑
我意识到我不需要递归定义中的交叉连接。虽然它不会影响后者的存在语句的结果,但它对性能不利。
| 归档时间: |
|
| 查看次数: |
5384 次 |
| 最近记录: |