[英]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.