我有一个无法解决的SQL问题
有两个表mms
和mms_mv
通过object_id
链接。
mms_mv
是一个多值表,内容是组成员身份,组管理员也可以是其他组。
这在SQL Server上运行
mms
:
|object_id|attribute_type|objectSid|
| 1 |user | a |
| 2 | group | b |
| 3 | group | c |
| 4 | group | d |
| 5 | group | f
mms_mv
:
|object_id|attribute_name|reference_id|
| 2 | member | 1 |
| 3 | manager | 1 |
| 4 | manager | 2 |
我试图找出用户可以通过嵌套组直接或间接管理哪些组。
在上面的示例中,用户(1)是组号2的成员,组2是组4的管理员 用户1直接是第3组的经理。
用户可以管理哪些群组?
所以我需要的输出是第3组和第4组
select
accountname, objectsid, mms1.reference_id as ManagerID,
mms2.object_id
from
dbo.mms_mv_link as mms1 with (nolock)
inner join
dbo.mms_metaverse as mms2 with (nolock) on mms1.object_id = mms2.object_id
where
mms2.object_type ='group'
and mms1.attribute_name = 'manager'
and mms1.reference_id in (1, 3)
这是我想出的最好的,以找出我提交的所有Group id和用户ID中的哪一个是Group of Manager。我使用其他查找来获取用户所在的组。
我的问题是嵌套组,通过长时间思考和谷歌搜索我不确定是否甚至可以创建这样的查询。
我可以找出用户所属的所有群组,但我还需要这些群组所属的群组。
如果有人有一些想法或提示让我想出这个,我很高兴。
如果您推荐一本涵盖此类复杂查询的优秀SQL书籍,我感到非常高兴。
谢谢大家的帮助。
答案 0 :(得分:0)
我认为以下递归CTE会给你你想要的东西:
;WITH cte AS
(
SELECT m2.object_id AS groupID, m2.attribute_name
FROM @mms AS m1
INNER JOIN @mms_mv AS m2 ON m1.object_id = m2.reference_id
INNER JOIN @mms m3 ON m2.object_id = m3.object_id
WHERE m1.attribute_type = 'user' AND m3.attribute_type = 'group'
UNION ALL
SELECT m.object_id AS groupID, m.attribute_name
FROM cte AS c
INNER JOIN @mms_mv AS m ON c.groupID = m.reference_id
)
SELECT *
FROM cte
WHERE attribute_name <> 'member'
CTE的所谓'锚'查询返回每个用户管理或成为其成员的所有组。使用递归,我们可以获得由原始集合或任何“中间”集合管理的所有其他组。
将这些数据作为输入:
DECLARE @mms TABLE (object_id INT, attribute_type VARCHAR(10), objectSid VARCHAR(10))
DECLARE @mms_mv TABLE (object_id INT, attribute_name VARCHAR(10), reference_id INT)
INSERT @mms VALUES
( 1, 'user', 'a'),
( 2, 'group', 'b'),
( 3, 'group', 'c'),
( 4, 'group', 'd'),
( 5, 'group', 'f')
INSERT @mms_mv VALUES
( 2, 'member', 1),
( 3, 'manager', 1),
( 4, 'manager', 2),
( 5, 'manager', 3)
以上查询产生以下输出:
groupID attribute_name
----------------------
3 manager
5 manager
4 manager