SQL Server:查询多值表递归

时间:2014-11-21 13:43:09

标签: sql sql-server

我有一个无法解决的SQL问题

有两个表mmsmms_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书籍,我感到非常高兴。

谢谢大家的帮助。

1 个答案:

答案 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