繁体   English   中英

如何使这种选择的组和成员更简单,更有效?

[英]How can I make a this selection of groups and members simpler and more efficient?

背景

我有一个表, 用户表和一个group_members表。

groups { group_ varchar(50) not null, etc... }
users  { user_id varchar(50) not null, etc... }
group_members { group_ varchar(50 not null, member varchar(50) not null }

我的要求是,一个组可以将其他组作为成员。 必须将用户视为所有用户所属的所有组的成员。
例如,请考虑这些表中的以下数据:

group_members              | groups         | users    |
========================== | ============== | ======== |
group_          member     | group_         | user_id  |
-------------------------- | -------------- | -------- |
'SYSTEM_ADMIN'  'OE_ADMIN' | 'SYSTEM_ADMIN' | 'USER    |
'SYSTEM_ADMIN'  'AR_ADMIN' | 'OE_ADMIN'     |          |
'SYSTEM_ADMIN'  'USER'     | 'AR_ADMIN'     |          |

我想要的问题询问结果是“ USER”的成员属于哪个组? 应该

member
==============
'SYSTEM_ADMIN'
'OE_ADMIN'
'AR_ADMIN'

我已经构建了以下查询,并为我提供了所需的结果,但是看起来有点复杂。

WITH GM
AS (
    SELECT GROUP_, MEMBER FROM group_members 
       WHERE member IN (SELECT group_ FROM groups)
)
SELECT group_ FROM group_members WHERE member = 'USER'
UNION
SELECT MEMBER AS GROUP_ FROM GM 
   WHERE group_ in (SELECT group_ FROM group_members WHERE member = 'USER')

关于如何使此查询更简单或更混乱的任何建议?

您的递归CTE看起来不错。

效果如何?

我认为没有任何有效的方法可以使它更简单-递归CTE总是看起来很凌乱。

WHERE IN等效于JOIN,但我不认为它更具可读性,并且执行计划应该相当等效。

您的根行可以在递归行之前表示为CTE,但实际上并不会节省太多可读性:

WITH root AS ()
     ,CTE AS ()
SELECT FROM ROOT 
    UNION
SELECT FROM CTE

无论如何,您都可以将其放在视图或内联表值函数(带有参数)中,以使其易于在系统中的其他位置使用,因此不必太多查看。

我为层次结构所做的事情是构建更高性能的扁平化/非规范化版本,并在触发器或计时器上对其进行更新,并将其用作只读性能增强器。 例如,在我们建立的技术支持系统中,可以在一个层次结构中标记问题,当选择一个孩子时,我们填写了所有父母(打印机-> hp-> laserjet),因此很容易查询以下问题任何版本的Windows上的hp打印机,或Windows XP上的Laserjets问题。

根据@Cade Roux的回答,进一步的思考将我引导至以下存储过程

ALTER PROCEDURE GetUserGroups
@user_id varchar(50)
AS
BEGIN
SET NOCOUNT ON;

SELECT group_ FROM group_members WHERE member = @user_id
UNION
SELECT MEMBER AS GROUP_ FROM group_members
WHERE group_ IN (SELECT group_ FROM group_members WHERE member = @user_id) 
      AND member != @user_id
END

这简化了原始查询,并正确满足了我的要求,以获取@user_id所属的组名列表以及作为顶级组成员的组名。

此代码仅允许将组中的组提高到一个级别。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM